// 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/common/capsule.h"

#include <stdbool.h>

#include <cstddef>
#include <cstdint>
#include <limits>
#include <ostream>
#include <string>
#include <type_traits>
#include <utility>
#include <variant>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/common/platform/api/quiche_bug_tracker.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_buffer_allocator.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/common/quiche_data_writer.h"
#include "quiche/common/quiche_ip_address.h"
#include "quiche/common/quiche_socket_address.h"
#include "quiche/common/quiche_status_utils.h"
#include "quiche/common/wire_serialization.h"
#include "quiche/web_transport/web_transport.h"

namespace quiche {

std::string CapsuleTypeToString(CapsuleType capsule_type) {
  switch (capsule_type) {
    case CapsuleType::DATAGRAM:
      return "DATAGRAM";
    case CapsuleType::LEGACY_DATAGRAM:
      return "LEGACY_DATAGRAM";
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      return "LEGACY_DATAGRAM_WITHOUT_CONTEXT";
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      return "CLOSE_WEBTRANSPORT_SESSION";
    case CapsuleType::DRAIN_WEBTRANSPORT_SESSION:
      return "DRAIN_WEBTRANSPORT_SESSION";
    case CapsuleType::ADDRESS_REQUEST:
      return "ADDRESS_REQUEST";
    case CapsuleType::ADDRESS_ASSIGN:
      return "ADDRESS_ASSIGN";
    case CapsuleType::ROUTE_ADVERTISEMENT:
      return "ROUTE_ADVERTISEMENT";
    case CapsuleType::WT_STREAM:
      return "WT_STREAM";
    case CapsuleType::WT_STREAM_WITH_FIN:
      return "WT_STREAM_WITH_FIN";
    case CapsuleType::WT_RESET_STREAM:
      return "WT_RESET_STREAM";
    case CapsuleType::WT_STOP_SENDING:
      return "WT_STOP_SENDING";
    case CapsuleType::WT_MAX_STREAM_DATA:
      return "WT_MAX_STREAM_DATA";
    case CapsuleType::WT_MAX_STREAMS_BIDI:
      return "WT_MAX_STREAMS_BIDI";
    case CapsuleType::WT_MAX_STREAMS_UNIDI:
      return "WT_MAX_STREAMS_UNIDI";
    case CapsuleType::COMPRESSION_ASSIGN:
      return "COMPRESSION_ASSIGN";
    case CapsuleType::COMPRESSION_CLOSE:
      return "COMPRESSION_CLOSE";
  }
  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;
}

// static
Capsule Capsule::Datagram(absl::string_view http_datagram_payload) {
  return Capsule(DatagramCapsule{http_datagram_payload});
}

// static
Capsule Capsule::LegacyDatagram(absl::string_view http_datagram_payload) {
  return Capsule(LegacyDatagramCapsule{http_datagram_payload});
}

// static
Capsule Capsule::LegacyDatagramWithoutContext(
    absl::string_view http_datagram_payload) {
  return Capsule(LegacyDatagramWithoutContextCapsule{http_datagram_payload});
}

// static
Capsule Capsule::CloseWebTransportSession(
    webtransport::SessionErrorCode error_code,
    absl::string_view error_message) {
  return Capsule(CloseWebTransportSessionCapsule({error_code, error_message}));
}

// static
Capsule Capsule::AddressRequest() { return Capsule(AddressRequestCapsule()); }

// static
Capsule Capsule::AddressAssign() { return Capsule(AddressAssignCapsule()); }

// static
Capsule Capsule::RouteAdvertisement() {
  return Capsule(RouteAdvertisementCapsule());
}

// static
Capsule Capsule::CompressionAssign() {
  return Capsule(CompressionAssignCapsule());
}

// static
Capsule Capsule::CompressionClose() {
  return Capsule(CompressionCloseCapsule());
}

// static
Capsule Capsule::Unknown(uint64_t capsule_type,
                         absl::string_view unknown_capsule_data) {
  return Capsule(UnknownCapsule{capsule_type, unknown_capsule_data});
}

bool Capsule::operator==(const Capsule& other) const {
  return capsule_ == other.capsule_;
}

std::string DatagramCapsule::ToString() const {
  return absl::StrCat("DATAGRAM[",
                      absl::BytesToHexString(http_datagram_payload), "]");
}

std::string LegacyDatagramCapsule::ToString() const {
  return absl::StrCat("LEGACY_DATAGRAM[",
                      absl::BytesToHexString(http_datagram_payload), "]");
}

std::string LegacyDatagramWithoutContextCapsule::ToString() const {
  return absl::StrCat("LEGACY_DATAGRAM_WITHOUT_CONTEXT[",
                      absl::BytesToHexString(http_datagram_payload), "]");
}

std::string CloseWebTransportSessionCapsule::ToString() const {
  return absl::StrCat("CLOSE_WEBTRANSPORT_SESSION(error_code=", error_code,
                      ",error_message=\"", error_message, "\")");
}

std::string DrainWebTransportSessionCapsule::ToString() const {
  return "DRAIN_WEBTRANSPORT_SESSION()";
}

std::string AddressRequestCapsule::ToString() const {
  std::string rv = "ADDRESS_REQUEST[";
  for (auto requested_address : requested_addresses) {
    absl::StrAppend(&rv, "(", requested_address.request_id, "-",
                    requested_address.ip_prefix.ToString(), ")");
  }
  absl::StrAppend(&rv, "]");
  return rv;
}

std::string AddressAssignCapsule::ToString() const {
  std::string rv = "ADDRESS_ASSIGN[";
  for (auto assigned_address : assigned_addresses) {
    absl::StrAppend(&rv, "(", assigned_address.request_id, "-",
                    assigned_address.ip_prefix.ToString(), ")");
  }
  absl::StrAppend(&rv, "]");
  return rv;
}

std::string CompressionAssignCapsule::ToString() const {
  return absl::StrCat("COMPRESSION_ASSIGN[", context_id, ", ",
                      ip_address_port.ToString(), "]");
}

std::string CompressionCloseCapsule::ToString() const {
  return absl::StrCat("COMPRESSION_CLOSE[", context_id, "]");
}

std::string RouteAdvertisementCapsule::ToString() const {
  std::string rv = "ROUTE_ADVERTISEMENT[";
  for (auto ip_address_range : ip_address_ranges) {
    absl::StrAppend(&rv, "(", ip_address_range.start_ip_address.ToString(), "-",
                    ip_address_range.end_ip_address.ToString(), "-",
                    static_cast<int>(ip_address_range.ip_protocol), ")");
  }
  absl::StrAppend(&rv, "]");
  return rv;
}

std::string UnknownCapsule::ToString() const {
  return absl::StrCat("Unknown(", type, ") [", absl::BytesToHexString(payload),
                      "]");
}

std::string WebTransportStreamDataCapsule::ToString() const {
  return absl::StrCat(CapsuleTypeToString(capsule_type()),
                      " [stream_id=", stream_id,
                      ", data=", absl::BytesToHexString(data), "]");
}

std::string WebTransportResetStreamCapsule::ToString() const {
  return absl::StrCat("WT_RESET_STREAM(stream_id=", stream_id,
                      ", error_code=", error_code, ")");
}

std::string WebTransportStopSendingCapsule::ToString() const {
  return absl::StrCat("WT_STOP_SENDING(stream_id=", stream_id,
                      ", error_code=", error_code, ")");
}

std::string WebTransportMaxStreamDataCapsule::ToString() const {
  return absl::StrCat("WT_MAX_STREAM_DATA (stream_id=", stream_id,
                      ", max_stream_data=", max_stream_data, ")");
}

std::string WebTransportMaxStreamsCapsule::ToString() const {
  return absl::StrCat(CapsuleTypeToString(capsule_type()),
                      " (max_streams=", max_stream_count, ")");
}

std::string Capsule::ToString() const {
  return std::visit([](const auto& capsule) { return capsule.ToString(); },
                    capsule_);
}

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);
}

// Serialization logic for quiche::PrefixWithId.
class WirePrefixWithId {
 public:
  using DataType = PrefixWithId;

  WirePrefixWithId(const PrefixWithId& prefix) : prefix_(prefix) {}

  size_t GetLengthOnWire() {
    return ComputeLengthOnWire(
        WireVarInt62(prefix_.request_id),
        WireUint8(prefix_.ip_prefix.address().IsIPv4() ? 4 : 6),
        WireBytes(prefix_.ip_prefix.address().ToPackedString()),
        WireUint8(prefix_.ip_prefix.prefix_length()));
  }

  absl::Status SerializeIntoWriter(QuicheDataWriter& writer) {
    return AppendToStatus(
        quiche::SerializeIntoWriter(
            writer, WireVarInt62(prefix_.request_id),
            WireUint8(prefix_.ip_prefix.address().IsIPv4() ? 4 : 6),
            WireBytes(prefix_.ip_prefix.address().ToPackedString()),
            WireUint8(prefix_.ip_prefix.prefix_length())),
        " while serializing a PrefixWithId");
  }

 private:
  const PrefixWithId& prefix_;
};

// Serialization logic for quiche::IpAddressRange.
class WireIpAddressRange {
 public:
  using DataType = IpAddressRange;

  explicit WireIpAddressRange(const IpAddressRange& range) : range_(range) {}

  size_t GetLengthOnWire() {
    return ComputeLengthOnWire(
        WireUint8(range_.start_ip_address.IsIPv4() ? 4 : 6),
        WireBytes(range_.start_ip_address.ToPackedString()),
        WireBytes(range_.end_ip_address.ToPackedString()),
        WireUint8(range_.ip_protocol));
  }

  absl::Status SerializeIntoWriter(QuicheDataWriter& writer) {
    return AppendToStatus(
        ::quiche::SerializeIntoWriter(
            writer, WireUint8(range_.start_ip_address.IsIPv4() ? 4 : 6),
            WireBytes(range_.start_ip_address.ToPackedString()),
            WireBytes(range_.end_ip_address.ToPackedString()),
            WireUint8(range_.ip_protocol)),
        " while serializing an IpAddressRange");
  }

 private:
  const IpAddressRange& range_;
};

template <typename... T>
absl::StatusOr<quiche::QuicheBuffer> SerializeCapsuleFields(
    CapsuleType type, QuicheBufferAllocator* allocator, T... fields) {
  size_t capsule_payload_size = ComputeLengthOnWire(fields...);
  return SerializeIntoBuffer(allocator, WireVarInt62(type),
                             WireVarInt62(capsule_payload_size), fields...);
}

absl::StatusOr<quiche::QuicheBuffer> SerializeCapsuleWithStatus(
    const Capsule& capsule, quiche::QuicheBufferAllocator* allocator) {
  switch (capsule.capsule_type()) {
    case CapsuleType::DATAGRAM:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireBytes(capsule.datagram_capsule().http_datagram_payload));
    case CapsuleType::LEGACY_DATAGRAM:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireBytes(capsule.legacy_datagram_capsule().http_datagram_payload));
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireBytes(capsule.legacy_datagram_without_context_capsule()
                        .http_datagram_payload));
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireUint32(capsule.close_web_transport_session_capsule().error_code),
          WireBytes(
              capsule.close_web_transport_session_capsule().error_message));
    case CapsuleType::DRAIN_WEBTRANSPORT_SESSION:
      return SerializeCapsuleFields(capsule.capsule_type(), allocator);
    case CapsuleType::ADDRESS_REQUEST:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireSpan<WirePrefixWithId>(absl::MakeConstSpan(
              capsule.address_request_capsule().requested_addresses)));
    case CapsuleType::ADDRESS_ASSIGN:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireSpan<WirePrefixWithId>(absl::MakeConstSpan(
              capsule.address_assign_capsule().assigned_addresses)));
    case CapsuleType::ROUTE_ADVERTISEMENT:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireSpan<WireIpAddressRange>(absl::MakeConstSpan(
              capsule.route_advertisement_capsule().ip_address_ranges)));
    case CapsuleType::WT_STREAM:
    case CapsuleType::WT_STREAM_WITH_FIN:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireVarInt62(capsule.web_transport_stream_data().stream_id),
          WireBytes(capsule.web_transport_stream_data().data));
    case CapsuleType::WT_RESET_STREAM:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireVarInt62(capsule.web_transport_reset_stream().stream_id),
          WireVarInt62(capsule.web_transport_reset_stream().error_code));
    case CapsuleType::WT_STOP_SENDING:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireVarInt62(capsule.web_transport_stop_sending().stream_id),
          WireVarInt62(capsule.web_transport_stop_sending().error_code));
    case CapsuleType::WT_MAX_STREAM_DATA:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireVarInt62(capsule.web_transport_max_stream_data().stream_id),
          WireVarInt62(
              capsule.web_transport_max_stream_data().max_stream_data));
    case CapsuleType::WT_MAX_STREAMS_BIDI:
    case CapsuleType::WT_MAX_STREAMS_UNIDI:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireVarInt62(capsule.web_transport_max_streams().max_stream_count));
    case CapsuleType::COMPRESSION_ASSIGN:
      QUICHE_DCHECK(capsule.compression_assign_capsule().ip_address_port ==
                        quiche::QuicheSocketAddress() ||
                    capsule.compression_assign_capsule()
                            .ip_address_port.host()
                            .ToPackedString()
                            .size() == QuicheIpAddress::kIPv4AddressSize ||
                    capsule.compression_assign_capsule()
                            .ip_address_port.host()
                            .ToPackedString()
                            .size() == QuicheIpAddress::kIPv6AddressSize);
      if (capsule.compression_assign_capsule()
              .ip_address_port.IsInitialized()) {
        return SerializeCapsuleFields(
            capsule.capsule_type(), allocator,
            WireVarInt62(capsule.compression_assign_capsule().context_id),
            WireUint8(capsule.compression_assign_capsule()
                                  .ip_address_port.host()
                                  .AddressFamilyToInt() == AF_INET
                          ? 4
                          : 6),
            WireBytes(capsule.compression_assign_capsule()
                          .ip_address_port.host()
                          .ToPackedString()),
            WireUint16(
                capsule.compression_assign_capsule().ip_address_port.port()));
      }
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireVarInt62(capsule.compression_assign_capsule().context_id),
          WireUint8(0));
    case CapsuleType::COMPRESSION_CLOSE:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireVarInt62(capsule.compression_close_capsule().context_id));
    default:
      return SerializeCapsuleFields(
          capsule.capsule_type(), allocator,
          WireBytes(capsule.unknown_capsule().payload));
  }
}

QuicheBuffer SerializeDatagramCapsuleHeader(uint64_t datagram_size,
                                            QuicheBufferAllocator* allocator) {
  absl::StatusOr<QuicheBuffer> buffer =
      SerializeIntoBuffer(allocator, WireVarInt62(CapsuleType::DATAGRAM),
                          WireVarInt62(datagram_size));
  if (!buffer.ok()) {
    return QuicheBuffer();
  }
  return *std::move(buffer);
}

QUICHE_EXPORT QuicheBuffer SerializeWebTransportStreamCapsuleHeader(
    webtransport::StreamId stream_id, bool fin, uint64_t write_size,
    QuicheBufferAllocator* allocator) {
  absl::StatusOr<QuicheBuffer> buffer = SerializeIntoBuffer(
      allocator,
      WireVarInt62(fin ? CapsuleType::WT_STREAM_WITH_FIN
                       : CapsuleType::WT_STREAM),
      WireVarInt62(write_size + QuicheDataWriter::GetVarInt62Len(stream_id)),
      WireVarInt62(stream_id));
  if (!buffer.ok()) {
    return QuicheBuffer();
  }
  return *std::move(buffer);
}

QuicheBuffer SerializeCapsule(const Capsule& capsule,
                              quiche::QuicheBufferAllocator* allocator) {
  absl::StatusOr<QuicheBuffer> serialized =
      SerializeCapsuleWithStatus(capsule, allocator);
  if (!serialized.ok()) {
    QUICHE_BUG(capsule_serialization_failed)
        << "Failed to serialize the following capsule:\n"
        << capsule << "Serialization error: " << serialized.status();
    return QuicheBuffer();
  }
  return *std::move(serialized);
}

bool CapsuleParser::IngestCapsuleFragment(absl::string_view capsule_fragment) {
  if (parsing_error_occurred_) {
    return false;
  }
  absl::StrAppend(&buffered_data_, capsule_fragment);
  while (true) {
    const absl::StatusOr<size_t> buffered_data_read = AttemptParseCapsule();
    if (!buffered_data_read.ok()) {
      ReportParseFailure(buffered_data_read.status().message());
      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;
}

namespace {
absl::Status ReadWebTransportStreamId(QuicheDataReader& reader,
                                      webtransport::StreamId& id) {
  uint64_t raw_id;
  if (!reader.ReadVarInt62(&raw_id)) {
    return absl::InvalidArgumentError("Failed to read WebTransport Stream ID");
  }
  if (raw_id > std::numeric_limits<uint32_t>::max()) {
    return absl::InvalidArgumentError("Stream ID does not fit into a uint32_t");
  }
  id = static_cast<webtransport::StreamId>(raw_id);
  return absl::OkStatus();
}

absl::StatusOr<Capsule> ParseCapsulePayload(QuicheDataReader& reader,
                                            CapsuleType type) {
  switch (type) {
    case CapsuleType::DATAGRAM:
      return Capsule::Datagram(reader.ReadRemainingPayload());
    case CapsuleType::LEGACY_DATAGRAM:
      return Capsule::LegacyDatagram(reader.ReadRemainingPayload());
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      return Capsule::LegacyDatagramWithoutContext(
          reader.ReadRemainingPayload());
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION: {
      CloseWebTransportSessionCapsule capsule;
      if (!reader.ReadUInt32(&capsule.error_code)) {
        return absl::InvalidArgumentError(
            "Unable to parse capsule CLOSE_WEBTRANSPORT_SESSION error code");
      }
      capsule.error_message = reader.ReadRemainingPayload();
      return Capsule(std::move(capsule));
    }
    case CapsuleType::DRAIN_WEBTRANSPORT_SESSION:
      return Capsule(DrainWebTransportSessionCapsule());
    case CapsuleType::ADDRESS_REQUEST: {
      AddressRequestCapsule capsule;
      while (!reader.IsDoneReading()) {
        PrefixWithId requested_address;
        if (!reader.ReadVarInt62(&requested_address.request_id)) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ADDRESS_REQUEST request ID");
        }
        uint8_t address_family;
        if (!reader.ReadUInt8(&address_family)) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ADDRESS_REQUEST family");
        }
        if (address_family != 4 && address_family != 6) {
          return absl::InvalidArgumentError("Bad ADDRESS_REQUEST family");
        }
        absl::string_view ip_address_bytes;
        if (!reader.ReadStringPiece(&ip_address_bytes,
                                    address_family == 4
                                        ? QuicheIpAddress::kIPv4AddressSize
                                        : QuicheIpAddress::kIPv6AddressSize)) {
          return absl::InvalidArgumentError(
              "Unable to read capsule ADDRESS_REQUEST address");
        }
        quiche::QuicheIpAddress ip_address;
        if (!ip_address.FromPackedString(ip_address_bytes.data(),
                                         ip_address_bytes.size())) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ADDRESS_REQUEST address");
        }
        uint8_t ip_prefix_length;
        if (!reader.ReadUInt8(&ip_prefix_length)) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ADDRESS_REQUEST IP prefix length");
        }
        if (ip_prefix_length > QuicheIpPrefix(ip_address).prefix_length()) {
          return absl::InvalidArgumentError("Invalid IP prefix length");
        }
        requested_address.ip_prefix =
            QuicheIpPrefix(ip_address, ip_prefix_length);
        capsule.requested_addresses.push_back(requested_address);
      }
      return Capsule(std::move(capsule));
    }
    case CapsuleType::ADDRESS_ASSIGN: {
      AddressAssignCapsule capsule;
      while (!reader.IsDoneReading()) {
        PrefixWithId assigned_address;
        if (!reader.ReadVarInt62(&assigned_address.request_id)) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ADDRESS_ASSIGN request ID");
        }
        uint8_t address_family;
        if (!reader.ReadUInt8(&address_family)) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ADDRESS_ASSIGN family");
        }
        if (address_family != 4 && address_family != 6) {
          return absl::InvalidArgumentError("Bad ADDRESS_ASSIGN family");
        }
        absl::string_view ip_address_bytes;
        if (!reader.ReadStringPiece(&ip_address_bytes,
                                    address_family == 4
                                        ? QuicheIpAddress::kIPv4AddressSize
                                        : QuicheIpAddress::kIPv6AddressSize)) {
          return absl::InvalidArgumentError(
              "Unable to read capsule ADDRESS_ASSIGN address");
        }
        quiche::QuicheIpAddress ip_address;
        if (!ip_address.FromPackedString(ip_address_bytes.data(),
                                         ip_address_bytes.size())) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ADDRESS_ASSIGN address");
        }
        uint8_t ip_prefix_length;
        if (!reader.ReadUInt8(&ip_prefix_length)) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ADDRESS_ASSIGN IP prefix length");
        }
        if (ip_prefix_length > QuicheIpPrefix(ip_address).prefix_length()) {
          return absl::InvalidArgumentError("Invalid IP prefix length");
        }
        assigned_address.ip_prefix =
            QuicheIpPrefix(ip_address, ip_prefix_length);
        capsule.assigned_addresses.push_back(assigned_address);
      }
      return Capsule(std::move(capsule));
    }
    case CapsuleType::ROUTE_ADVERTISEMENT: {
      RouteAdvertisementCapsule capsule;
      while (!reader.IsDoneReading()) {
        uint8_t address_family;
        if (!reader.ReadUInt8(&address_family)) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ROUTE_ADVERTISEMENT family");
        }
        if (address_family != 4 && address_family != 6) {
          return absl::InvalidArgumentError("Bad ROUTE_ADVERTISEMENT family");
        }
        IpAddressRange ip_address_range;
        absl::string_view start_ip_address_bytes;
        if (!reader.ReadStringPiece(&start_ip_address_bytes,
                                    address_family == 4
                                        ? QuicheIpAddress::kIPv4AddressSize
                                        : QuicheIpAddress::kIPv6AddressSize)) {
          return absl::InvalidArgumentError(
              "Unable to read capsule ROUTE_ADVERTISEMENT start address");
        }
        if (!ip_address_range.start_ip_address.FromPackedString(
                start_ip_address_bytes.data(), start_ip_address_bytes.size())) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ROUTE_ADVERTISEMENT start address");
        }
        absl::string_view end_ip_address_bytes;
        if (!reader.ReadStringPiece(&end_ip_address_bytes,
                                    address_family == 4
                                        ? QuicheIpAddress::kIPv4AddressSize
                                        : QuicheIpAddress::kIPv6AddressSize)) {
          return absl::InvalidArgumentError(
              "Unable to read capsule ROUTE_ADVERTISEMENT end address");
        }
        if (!ip_address_range.end_ip_address.FromPackedString(
                end_ip_address_bytes.data(), end_ip_address_bytes.size())) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ROUTE_ADVERTISEMENT end address");
        }
        if (!reader.ReadUInt8(&ip_address_range.ip_protocol)) {
          return absl::InvalidArgumentError(
              "Unable to parse capsule ROUTE_ADVERTISEMENT IP protocol");
        }
        capsule.ip_address_ranges.push_back(ip_address_range);
      }
      return Capsule(std::move(capsule));
    }
    case CapsuleType::WT_STREAM:
    case CapsuleType::WT_STREAM_WITH_FIN: {
      WebTransportStreamDataCapsule capsule;
      capsule.fin = (type == CapsuleType::WT_STREAM_WITH_FIN);
      QUICHE_RETURN_IF_ERROR(
          ReadWebTransportStreamId(reader, capsule.stream_id));
      capsule.data = reader.ReadRemainingPayload();
      return Capsule(std::move(capsule));
    }
    case CapsuleType::WT_RESET_STREAM: {
      WebTransportResetStreamCapsule capsule;
      QUICHE_RETURN_IF_ERROR(
          ReadWebTransportStreamId(reader, capsule.stream_id));
      if (!reader.ReadVarInt62(&capsule.error_code)) {
        return absl::InvalidArgumentError(
            "Failed to parse the RESET_STREAM error code");
      }
      return Capsule(std::move(capsule));
    }
    case CapsuleType::WT_STOP_SENDING: {
      WebTransportStopSendingCapsule capsule;
      QUICHE_RETURN_IF_ERROR(
          ReadWebTransportStreamId(reader, capsule.stream_id));
      if (!reader.ReadVarInt62(&capsule.error_code)) {
        return absl::InvalidArgumentError(
            "Failed to parse the STOP_SENDING error code");
      }
      return Capsule(std::move(capsule));
    }
    case CapsuleType::WT_MAX_STREAM_DATA: {
      WebTransportMaxStreamDataCapsule capsule;
      QUICHE_RETURN_IF_ERROR(
          ReadWebTransportStreamId(reader, capsule.stream_id));
      if (!reader.ReadVarInt62(&capsule.max_stream_data)) {
        return absl::InvalidArgumentError(
            "Failed to parse the max stream data field");
      }
      return Capsule(std::move(capsule));
    }
    case CapsuleType::WT_MAX_STREAMS_UNIDI:
    case CapsuleType::WT_MAX_STREAMS_BIDI: {
      WebTransportMaxStreamsCapsule capsule;
      capsule.stream_type = type == CapsuleType::WT_MAX_STREAMS_UNIDI
                                ? webtransport::StreamType::kUnidirectional
                                : webtransport::StreamType::kBidirectional;
      if (!reader.ReadVarInt62(&capsule.max_stream_count)) {
        return absl::InvalidArgumentError(
            "Failed to parse the max streams field");
      }
      return Capsule(std::move(capsule));
    }
    case CapsuleType::COMPRESSION_ASSIGN: {
      CompressionAssignCapsule capsule;
      if (!reader.ReadVarInt62(&capsule.context_id)) {
        return absl::InvalidArgumentError(
            "Failed to parse the compression assign context ID");
      }
      uint8_t address_family;
      if (!reader.ReadUInt8(&address_family)) {
        return absl::InvalidArgumentError(
            "Failed to parse the compression assign address family");
      }
      if (address_family != 0 && address_family != 4 && address_family != 6) {
        return absl::InvalidArgumentError(
            "Bad compression assign address family");
      }
      if (address_family == 0) {
        capsule.ip_address_port = QuicheSocketAddress();
        if (!reader.IsDoneReading()) {
          return absl::InvalidArgumentError(
              "Extra bytes in compression assign capsule");
        }
        return Capsule(std::move(capsule));
      }
      size_t address_size = address_family == 4
                                ? QuicheIpAddress::kIPv4AddressSize
                                : QuicheIpAddress::kIPv6AddressSize;
      absl::string_view ip_address_bytes;
      if (!reader.ReadStringPiece(&ip_address_bytes, address_size)) {
        return absl::InvalidArgumentError(
            "Failed to read the compression assign IP address");
      }
      quiche::QuicheIpAddress ip_address;
      if (!ip_address.FromPackedString(ip_address_bytes.data(), address_size)) {
        return absl::InvalidArgumentError(
            "Failed to parse the compression assign IP address");
      }
      QUICHE_LOG(INFO) << "CompressionAssignCapsule IP: "
                       << ip_address.ToString();
      uint16_t port;
      if (!reader.ReadUInt16(&port)) {
        return absl::InvalidArgumentError(
            "Failed to read the compression assign port");
      }
      capsule.ip_address_port = QuicheSocketAddress(ip_address, port);
      if (!reader.IsDoneReading()) {
        return absl::InvalidArgumentError(
            "Extra bytes in compression assign capsule");
      }
      return Capsule(std::move(capsule));
    }
    case CapsuleType::COMPRESSION_CLOSE: {
      CompressionCloseCapsule capsule;
      if (!reader.ReadVarInt62(&capsule.context_id)) {
        return absl::InvalidArgumentError(
            "Failed to parse the compression close context ID");
      }
      if (!reader.IsDoneReading()) {
        return absl::InvalidArgumentError(
            "Extra bytes in compression close capsule");
      }
      return Capsule(std::move(capsule));
    }
    default:
      return Capsule(UnknownCapsule{static_cast<uint64_t>(type),
                                    reader.ReadRemainingPayload()});
  }
}
}  // namespace

absl::StatusOr<size_t> CapsuleParser::AttemptParseCapsule() {
  QUICHE_DCHECK(!parsing_error_occurred_);
  if (buffered_data_.empty()) {
    return 0;
  }
  QuicheDataReader capsule_fragment_reader(buffered_data_);
  uint64_t capsule_type64;
  if (!capsule_fragment_reader.ReadVarInt62(&capsule_type64)) {
    QUICHE_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)) {
    QUICHE_DVLOG(2)
        << "Partial read: not enough data to read capsule length or "
           "full capsule data";
    return 0;
  }
  QuicheDataReader capsule_data_reader(capsule_data);
  absl::StatusOr<Capsule> capsule = ParseCapsulePayload(
      capsule_data_reader, static_cast<CapsuleType>(capsule_type64));
  QUICHE_RETURN_IF_ERROR(capsule.status());
  if (!visitor_->OnCapsule(*capsule)) {
    return absl::AbortedError("Visitor failed to process capsule");
  }
  return capsule_fragment_reader.PreviouslyReadPayload().length();
}

void CapsuleParser::ReportParseFailure(absl::string_view error_message) {
  if (parsing_error_occurred_) {
    QUICHE_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");
  }
}

bool PrefixWithId::operator==(const PrefixWithId& other) const {
  return request_id == other.request_id && ip_prefix == other.ip_prefix;
}

bool IpAddressRange::operator==(const IpAddressRange& other) const {
  return start_ip_address == other.start_ip_address &&
         end_ip_address == other.end_ip_address &&
         ip_protocol == other.ip_protocol;
}

bool AddressAssignCapsule::operator==(const AddressAssignCapsule& other) const {
  return assigned_addresses == other.assigned_addresses;
}

bool CompressionAssignCapsule::operator==(
    const CompressionAssignCapsule& other) const {
  return context_id == other.context_id &&
         ip_address_port == other.ip_address_port;
}

bool CompressionCloseCapsule::operator==(
    const CompressionCloseCapsule& other) const {
  return context_id == other.context_id;
}

bool AddressRequestCapsule::operator==(
    const AddressRequestCapsule& other) const {
  return requested_addresses == other.requested_addresses;
}

bool RouteAdvertisementCapsule::operator==(
    const RouteAdvertisementCapsule& other) const {
  return ip_address_ranges == other.ip_address_ranges;
}

bool WebTransportStreamDataCapsule::operator==(
    const WebTransportStreamDataCapsule& other) const {
  return stream_id == other.stream_id && data == other.data && fin == other.fin;
}

bool WebTransportResetStreamCapsule::operator==(
    const WebTransportResetStreamCapsule& other) const {
  return stream_id == other.stream_id && error_code == other.error_code;
}

bool WebTransportStopSendingCapsule::operator==(
    const WebTransportStopSendingCapsule& other) const {
  return stream_id == other.stream_id && error_code == other.error_code;
}

bool WebTransportMaxStreamDataCapsule::operator==(
    const WebTransportMaxStreamDataCapsule& other) const {
  return stream_id == other.stream_id &&
         max_stream_data == other.max_stream_data;
}

bool WebTransportMaxStreamsCapsule::operator==(
    const WebTransportMaxStreamsCapsule& other) const {
  return stream_type == other.stream_type &&
         max_stream_count == other.max_stream_count;
}

}  // namespace quiche
