// 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 "openssl/digest.h"
#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,

  kGoogleHandshakeMessage = 0x26ab,

  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::kGoogleHandshakeMessage:
      return "google_handshake_message";
    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::kGoogleHandshakeMessage:
    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, quiche::kVarInt62MaxValue);
}

TransportParameters::IntegerParameter::IntegerParameter(
    TransportParameters::TransportParameterId param_id)
    : TransportParameters::IntegerParameter::IntegerParameter(
          param_id, 0, 0, quiche::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 quiche::QuicheVariableLengthIntegerLength 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->WriteVarInt62WithForcedLength(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);
  if (google_handshake_message.has_value()) {
    absl::StrAppend(&rv, " ",
                    TransportParameterIdToString(kGoogleHandshakeMessage),
                    " length: ", google_handshake_message.value().length());
  }
  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,
                           quiche::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,
                                 quiche::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_handshake_message(other.google_handshake_message),
      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_handshake_message == rhs.google_handshake_message &&
        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 &&
      google_handshake_message.has_value()) {
    *error_details = "Server cannot send google_handshake_message";
    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(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_handshake_message
      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::kGoogleHandshakeMessage,
      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);
  }
  // google_handshake_message.
  if (in.google_handshake_message.has_value()) {
    max_transport_param_length += in.google_handshake_message.value().length();
  }

  // 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;
      // google_handshake_message
      case TransportParameters::kGoogleHandshakeMessage: {
        if (in.google_handshake_message.has_value()) {
          if (!writer.WriteVarInt62(
                  TransportParameters::kGoogleHandshakeMessage) ||
              !writer.WriteStringPieceVarInt62(
                  in.google_handshake_message.value())) {
            QUIC_BUG(Failed to write google_handshake_message)
                << "Failed to write google_handshake_message: "
                << in.google_handshake_message.value() << " 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::kGoogleHandshakeMessage:
        if (out->google_handshake_message.has_value()) {
          *error_details = "Received a second google_handshake_message";
          return false;
        }
        out->google_handshake_message =
            std::string(value_reader.ReadRemainingPayload());
        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
