// 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 "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"

#include <cstdint>
#include <cstring>

#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.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 : uint16_t {
  kOriginalConnectionId = 0,
  kIdleTimeout = 1,
  kStatelessResetToken = 2,
  kMaxPacketSize = 3,
  kInitialMaxData = 4,
  kInitialMaxStreamDataBidiLocal = 5,
  kInitialMaxStreamDataBidiRemote = 6,
  kInitialMaxStreamDataUni = 7,
  kInitialMaxStreamsBidi = 8,
  kInitialMaxStreamsUni = 9,
  kAckDelayExponent = 0xa,
  kMaxAckDelay = 0xb,
  kDisableMigration = 0xc,
  kPreferredAddress = 0xd,
  kActiveConnectionIdLimit = 0xe,

  kGoogleQuicParam = 18257,  // Used for non-standard Google-specific params.
  kGoogleQuicVersion =
      18258,  // Used to transmit version and supported_versions.
};

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.
const uint64_t kMinMaxPacketSizeTransportParam = 1200;
const uint64_t kDefaultMaxPacketSizeTransportParam = 65527;
const uint64_t kMaxAckDelayExponentTransportParam = 20;
const uint64_t kDefaultAckDelayExponentTransportParam = 3;
const uint64_t kMaxMaxAckDelayTransportParam = 16383;
const uint64_t kDefaultMaxAckDelayTransportParam = 25;
const size_t kStatelessResetTokenLength = 16;

std::string TransportParameterIdToString(
    TransportParameters::TransportParameterId param_id) {
  switch (param_id) {
    case TransportParameters::kOriginalConnectionId:
      return "original_connection_id";
    case TransportParameters::kIdleTimeout:
      return "idle_timeout";
    case TransportParameters::kStatelessResetToken:
      return "stateless_reset_token";
    case TransportParameters::kMaxPacketSize:
      return "max_packet_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::kDisableMigration:
      return "disable_migration";
    case TransportParameters::kPreferredAddress:
      return "preferred_address";
    case TransportParameters::kActiveConnectionIdLimit:
      return "active_connection_id_limit";
    case TransportParameters::kGoogleQuicParam:
      return "google";
    case TransportParameters::kGoogleQuicVersion:
      return "google-version";
  }
  return "Unknown(" + QuicTextUtils::Uint64ToString(param_id) + ")";
}

}  // 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_from_cbs_(false) {
  DCHECK_LE(min_value, default_value);
  DCHECK_LE(default_value, max_value);
  DCHECK_LE(max_value, kVarInt62MaxValue);
}

TransportParameters::IntegerParameter::IntegerParameter(
    TransportParameters::TransportParameterId param_id)
    : TransportParameters::IntegerParameter::IntegerParameter(
          param_id,
          0,
          0,
          kVarInt62MaxValue) {}

void TransportParameters::IntegerParameter::set_value(uint64_t value) {
  value_ = value;
}

uint64_t TransportParameters::IntegerParameter::value() const {
  return value_;
}

bool TransportParameters::IntegerParameter::IsValid() const {
  return min_value_ <= value_ && value_ <= max_value_;
}

bool TransportParameters::IntegerParameter::WriteToCbb(CBB* parent_cbb) const {
  DCHECK(IsValid());
  if (value_ == default_value_) {
    // Do not write if the value is default.
    return true;
  }
  uint8_t encoded_data[sizeof(uint64_t)] = {};
  QuicDataWriter writer(sizeof(encoded_data),
                        reinterpret_cast<char*>(encoded_data));
  writer.WriteVarInt62(value_);
  const uint16_t value_length = writer.length();
  DCHECK_LE(value_length, sizeof(encoded_data));
  const bool ok = CBB_add_u16(parent_cbb, param_id_) &&
                  CBB_add_u16(parent_cbb, value_length) &&
                  CBB_add_bytes(parent_cbb, encoded_data, value_length);
  QUIC_BUG_IF(!ok) << "Failed to write " << this;
  return ok;
}

bool TransportParameters::IntegerParameter::ReadFromCbs(CBS* const value_cbs) {
  if (has_been_read_from_cbs_) {
    QUIC_DLOG(ERROR) << "Received a second "
                     << TransportParameterIdToString(param_id_);
    return false;
  }
  has_been_read_from_cbs_ = true;
  QuicDataReader reader(reinterpret_cast<const char*>(CBS_data(value_cbs)),
                        CBS_len(value_cbs));
  QuicVariableLengthIntegerLength value_length = reader.PeekVarInt62Length();
  if (value_length == 0 || !reader.ReadVarInt62(&value_)) {
    QUIC_DLOG(ERROR) << "Failed to parse value for "
                     << TransportParameterIdToString(param_id_);
    return false;
  }
  if (!reader.IsDoneReading()) {
    QUIC_DLOG(ERROR) << "Received unexpected " << reader.BytesRemaining()
                     << " bytes after parsing " << this;
    return false;
  }
  if (!CBS_skip(value_cbs, value_length)) {
    QUIC_BUG << "Failed to advance CBS past value for " << this;
    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 ? " " : "";
  rv += TransportParameterIdToString(param_id_) + " ";
  rv += QuicTextUtils::Uint64ToString(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() {}

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 " +
         QuicTextUtils::HexEncode(
             reinterpret_cast<const char*>(stateless_reset_token.data()),
             stateless_reset_token.size()) +
         "]";
}

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 (version != 0) {
    rv += " version " + QuicVersionLabelToString(version);
  }
  if (!supported_versions.empty()) {
    rv += " supported_versions " +
          QuicVersionLabelVectorToString(supported_versions);
  }
  if (!original_connection_id.IsEmpty()) {
    rv += " " + TransportParameterIdToString(kOriginalConnectionId) + " " +
          original_connection_id.ToString();
  }
  rv += idle_timeout_milliseconds.ToString(/*for_use_in_list=*/true);
  if (!stateless_reset_token.empty()) {
    rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
          QuicTextUtils::HexEncode(
              reinterpret_cast<const char*>(stateless_reset_token.data()),
              stateless_reset_token.size());
  }
  rv += max_packet_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);
  if (disable_migration) {
    rv += " " + TransportParameterIdToString(kDisableMigration);
  }
  if (preferred_address) {
    rv += " " + TransportParameterIdToString(kPreferredAddress) + " " +
          preferred_address->ToString();
  }
  rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true);
  if (google_quic_params) {
    rv += " " + TransportParameterIdToString(kGoogleQuicParam);
  }
  rv += "]";
  return rv;
}

TransportParameters::TransportParameters()
    : version(0),
      original_connection_id(EmptyQuicConnectionId()),
      idle_timeout_milliseconds(kIdleTimeout),
      max_packet_size(kMaxPacketSize,
                      kDefaultMaxPacketSizeTransportParam,
                      kMinMaxPacketSizeTransportParam,
                      kVarInt62MaxValue),
      initial_max_data(kInitialMaxData),
      initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
      initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
      initial_max_stream_data_uni(kInitialMaxStreamDataUni),
      initial_max_streams_bidi(kInitialMaxStreamsBidi),
      initial_max_streams_uni(kInitialMaxStreamsUni),
      ack_delay_exponent(kAckDelayExponent,
                         kDefaultAckDelayExponentTransportParam,
                         0,
                         kMaxAckDelayExponentTransportParam),
      max_ack_delay(kMaxAckDelay,
                    kDefaultMaxAckDelayTransportParam,
                    0,
                    kMaxMaxAckDelayTransportParam),
      disable_migration(false),
      active_connection_id_limit(kActiveConnectionIdLimit)
// Important note: any new transport parameters must be added
// to TransportParameters::AreValid, SerializeTransportParameters and
// ParseTransportParameters.
{}

bool TransportParameters::AreValid() const {
  DCHECK(perspective == Perspective::IS_CLIENT ||
         perspective == Perspective::IS_SERVER);
  if (perspective == Perspective::IS_CLIENT && !stateless_reset_token.empty()) {
    QUIC_DLOG(ERROR) << "Client cannot send stateless reset token";
    return false;
  }
  if (perspective == Perspective::IS_CLIENT &&
      !original_connection_id.IsEmpty()) {
    QUIC_DLOG(ERROR) << "Client cannot send original connection ID";
    return false;
  }
  if (!stateless_reset_token.empty() &&
      stateless_reset_token.size() != kStatelessResetTokenLength) {
    QUIC_DLOG(ERROR) << "Stateless reset token has bad length "
                     << stateless_reset_token.size();
    return false;
  }
  if (perspective == Perspective::IS_CLIENT && preferred_address) {
    QUIC_DLOG(ERROR) << "Client cannot send preferred address";
    return false;
  }
  if (preferred_address && preferred_address->stateless_reset_token.size() !=
                               kStatelessResetTokenLength) {
    QUIC_DLOG(ERROR)
        << "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 << "Preferred address family failure";
    return false;
  }
  const bool ok = idle_timeout_milliseconds.IsValid() &&
                  max_packet_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() &&
                  active_connection_id_limit.IsValid();
  if (!ok) {
    QUIC_DLOG(ERROR) << "Invalid transport parameters " << *this;
  }
  return ok;
}

TransportParameters::~TransportParameters() = default;

bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
                                  const TransportParameters& in,
                                  std::vector<uint8_t>* out) {
  if (!in.AreValid()) {
    QUIC_DLOG(ERROR) << "Not serializing invalid transport parameters " << in;
    return false;
  }
  if (in.version == 0 || (in.perspective == Perspective::IS_SERVER &&
                          in.supported_versions.empty())) {
    QUIC_DLOG(ERROR) << "Refusing to serialize without versions";
    return false;
  }

  bssl::ScopedCBB cbb;
  // Empirically transport parameters generally fit within 128 bytes.
  // The CBB will grow to fit larger serializations if required.
  if (!CBB_init(cbb.get(), 128)) {
    QUIC_BUG << "Failed to initialize CBB for " << in;
    return false;
  }

  CBB params;
  // Add length of the transport parameters list.
  if (!CBB_add_u16_length_prefixed(cbb.get(), &params)) {
    QUIC_BUG << "Failed to write parameter length for " << in;
    return false;
  }

  // original_connection_id
  CBB original_connection_id_param;
  if (!in.original_connection_id.IsEmpty()) {
    DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
    if (!CBB_add_u16(&params, TransportParameters::kOriginalConnectionId) ||
        !CBB_add_u16_length_prefixed(&params, &original_connection_id_param) ||
        !CBB_add_bytes(
            &original_connection_id_param,
            reinterpret_cast<const uint8_t*>(in.original_connection_id.data()),
            in.original_connection_id.length())) {
      QUIC_BUG << "Failed to write original_connection_id "
               << in.original_connection_id << " for " << in;
      return false;
    }
  }

  if (!in.idle_timeout_milliseconds.WriteToCbb(&params)) {
    QUIC_BUG << "Failed to write idle_timeout for " << in;
    return false;
  }

  // stateless_reset_token
  CBB stateless_reset_token_param;
  if (!in.stateless_reset_token.empty()) {
    DCHECK_EQ(kStatelessResetTokenLength, in.stateless_reset_token.size());
    DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
    if (!CBB_add_u16(&params, TransportParameters::kStatelessResetToken) ||
        !CBB_add_u16_length_prefixed(&params, &stateless_reset_token_param) ||
        !CBB_add_bytes(&stateless_reset_token_param,
                       in.stateless_reset_token.data(),
                       in.stateless_reset_token.size())) {
      QUIC_BUG << "Failed to write stateless_reset_token of length "
               << in.stateless_reset_token.size() << " for " << in;
      return false;
    }
  }

  if (!in.max_packet_size.WriteToCbb(&params) ||
      !in.initial_max_data.WriteToCbb(&params) ||
      !in.initial_max_stream_data_bidi_local.WriteToCbb(&params) ||
      !in.initial_max_stream_data_bidi_remote.WriteToCbb(&params) ||
      !in.initial_max_stream_data_uni.WriteToCbb(&params) ||
      !in.initial_max_streams_bidi.WriteToCbb(&params) ||
      !in.initial_max_streams_uni.WriteToCbb(&params) ||
      !in.ack_delay_exponent.WriteToCbb(&params) ||
      !in.max_ack_delay.WriteToCbb(&params) ||
      !in.active_connection_id_limit.WriteToCbb(&params)) {
    QUIC_BUG << "Failed to write integers for " << in;
    return false;
  }

  // disable_migration
  if (in.disable_migration) {
    if (!CBB_add_u16(&params, TransportParameters::kDisableMigration) ||
        !CBB_add_u16(&params, 0u)) {  // 0 is the length of this parameter.
      QUIC_BUG << "Failed to write disable_migration for " << in;
      return false;
    }
  }

  // preferred_address
  CBB preferred_address_params, preferred_address_connection_id_param;
  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 << "Bad lengths " << *in.preferred_address;
      return false;
    }
    if (!CBB_add_u16(&params, TransportParameters::kPreferredAddress) ||
        !CBB_add_u16_length_prefixed(&params, &preferred_address_params) ||
        !CBB_add_bytes(
            &preferred_address_params,
            reinterpret_cast<const uint8_t*>(v4_address_bytes.data()),
            v4_address_bytes.length()) ||
        !CBB_add_u16(&preferred_address_params,
                     in.preferred_address->ipv4_socket_address.port()) ||
        !CBB_add_bytes(
            &preferred_address_params,
            reinterpret_cast<const uint8_t*>(v6_address_bytes.data()),
            v6_address_bytes.length()) ||
        !CBB_add_u16(&preferred_address_params,
                     in.preferred_address->ipv6_socket_address.port()) ||
        !CBB_add_u8_length_prefixed(&preferred_address_params,
                                    &preferred_address_connection_id_param) ||
        !CBB_add_bytes(&preferred_address_connection_id_param,
                       reinterpret_cast<const uint8_t*>(
                           in.preferred_address->connection_id.data()),
                       in.preferred_address->connection_id.length()) ||
        !CBB_add_bytes(&preferred_address_params,
                       in.preferred_address->stateless_reset_token.data(),
                       in.preferred_address->stateless_reset_token.size())) {
      QUIC_BUG << "Failed to write preferred_address for " << in;
      return false;
    }
  }

  // Google-specific non-standard parameter.
  CBB google_quic_params;
  if (in.google_quic_params) {
    const QuicData& serialized_google_quic_params =
        in.google_quic_params->GetSerialized();
    if (!CBB_add_u16(&params, TransportParameters::kGoogleQuicParam) ||
        !CBB_add_u16_length_prefixed(&params, &google_quic_params) ||
        !CBB_add_bytes(&google_quic_params,
                       reinterpret_cast<const uint8_t*>(
                           serialized_google_quic_params.data()),
                       serialized_google_quic_params.length())) {
      QUIC_BUG << "Failed to write Google params of length "
               << serialized_google_quic_params.length() << " for " << in;
      return false;
    }
  }

  // Google-specific version extension.
  CBB google_version_params;
  if (!CBB_add_u16(&params, TransportParameters::kGoogleQuicVersion) ||
      !CBB_add_u16_length_prefixed(&params, &google_version_params) ||
      !CBB_add_u32(&google_version_params, in.version)) {
    QUIC_BUG << "Failed to write Google version extension for " << in;
    return false;
  }
  CBB versions;
  if (in.perspective == Perspective::IS_SERVER) {
    if (!CBB_add_u8_length_prefixed(&google_version_params, &versions)) {
      QUIC_BUG << "Failed to write versions length for " << in;
      return false;
    }
    for (QuicVersionLabel version : in.supported_versions) {
      if (!CBB_add_u32(&versions, version)) {
        QUIC_BUG << "Failed to write supported version for " << in;
        return false;
      }
    }
  }

  if (!CBB_flush(cbb.get())) {
    QUIC_BUG << "Failed to flush CBB for " << in;
    return false;
  }
  out->resize(CBB_len(cbb.get()));
  memcpy(out->data(), CBB_data(cbb.get()), CBB_len(cbb.get()));
  QUIC_DLOG(INFO) << "Serialized " << in << " as " << CBB_len(cbb.get())
                  << " bytes";
  return true;
}

bool ParseTransportParameters(ParsedQuicVersion version,
                              Perspective perspective,
                              const uint8_t* in,
                              size_t in_len,
                              TransportParameters* out) {
  out->perspective = perspective;
  CBS cbs;
  CBS_init(&cbs, in, in_len);

  CBS params;
  if (!CBS_get_u16_length_prefixed(&cbs, &params)) {
    QUIC_DLOG(ERROR) << "Failed to parse the number of transport parameters";
    return false;
  }

  while (CBS_len(&params) > 0) {
    TransportParameters::TransportParameterId param_id;
    CBS value;
    static_assert(sizeof(param_id) == sizeof(uint16_t), "bad size");
    if (!CBS_get_u16(&params, reinterpret_cast<uint16_t*>(&param_id))) {
      QUIC_DLOG(ERROR) << "Failed to parse transport parameter ID";
      return false;
    }
    if (!CBS_get_u16_length_prefixed(&params, &value)) {
      QUIC_DLOG(ERROR) << "Failed to parse length of transport parameter "
                       << TransportParameterIdToString(param_id);
      return false;
    }
    bool parse_success = true;
    switch (param_id) {
      case TransportParameters::kOriginalConnectionId: {
        if (!out->original_connection_id.IsEmpty()) {
          QUIC_DLOG(ERROR) << "Received a second original connection ID";
          return false;
        }
        const size_t connection_id_length = CBS_len(&value);
        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
                connection_id_length, version.transport_version)) {
          QUIC_DLOG(ERROR) << "Received original connection ID of "
                           << "invalid length " << connection_id_length;
          return false;
        }
        out->original_connection_id.set_length(
            static_cast<uint8_t>(connection_id_length));
        if (out->original_connection_id.length() != 0) {
          memcpy(out->original_connection_id.mutable_data(), CBS_data(&value),
                 out->original_connection_id.length());
        }
      } break;
      case TransportParameters::kIdleTimeout:
        parse_success = out->idle_timeout_milliseconds.ReadFromCbs(&value);
        break;
      case TransportParameters::kStatelessResetToken:
        if (!out->stateless_reset_token.empty()) {
          QUIC_DLOG(ERROR) << "Received a second stateless reset token";
          return false;
        }
        if (CBS_len(&value) != kStatelessResetTokenLength) {
          QUIC_DLOG(ERROR) << "Received stateless reset token of "
                           << "invalid length " << CBS_len(&value);
          return false;
        }
        out->stateless_reset_token.assign(CBS_data(&value),
                                          CBS_data(&value) + CBS_len(&value));
        break;
      case TransportParameters::kMaxPacketSize:
        parse_success = out->max_packet_size.ReadFromCbs(&value);
        break;
      case TransportParameters::kInitialMaxData:
        parse_success = out->initial_max_data.ReadFromCbs(&value);
        break;
      case TransportParameters::kInitialMaxStreamDataBidiLocal:
        parse_success =
            out->initial_max_stream_data_bidi_local.ReadFromCbs(&value);
        break;
      case TransportParameters::kInitialMaxStreamDataBidiRemote:
        parse_success =
            out->initial_max_stream_data_bidi_remote.ReadFromCbs(&value);
        break;
      case TransportParameters::kInitialMaxStreamDataUni:
        parse_success = out->initial_max_stream_data_uni.ReadFromCbs(&value);
        break;
      case TransportParameters::kInitialMaxStreamsBidi:
        parse_success = out->initial_max_streams_bidi.ReadFromCbs(&value);
        break;
      case TransportParameters::kInitialMaxStreamsUni:
        parse_success = out->initial_max_streams_uni.ReadFromCbs(&value);
        break;
      case TransportParameters::kAckDelayExponent:
        parse_success = out->ack_delay_exponent.ReadFromCbs(&value);
        break;
      case TransportParameters::kMaxAckDelay:
        parse_success = out->max_ack_delay.ReadFromCbs(&value);
        break;
      case TransportParameters::kDisableMigration:
        if (out->disable_migration) {
          QUIC_DLOG(ERROR) << "Received a second disable migration";
          return false;
        }
        if (CBS_len(&value) != 0) {
          QUIC_DLOG(ERROR) << "Received disable migration of invalid length "
                           << CBS_len(&value);
          return false;
        }
        out->disable_migration = true;
        break;
      case TransportParameters::kPreferredAddress: {
        uint16_t ipv4_port, ipv6_port;
        in_addr ipv4_address;
        in6_addr ipv6_address;
        if (!CBS_copy_bytes(&value, reinterpret_cast<uint8_t*>(&ipv4_address),
                            sizeof(ipv4_address)) ||
            !CBS_get_u16(&value, &ipv4_port) ||
            !CBS_copy_bytes(&value, reinterpret_cast<uint8_t*>(&ipv6_address),
                            sizeof(ipv6_address)) ||
            !CBS_get_u16(&value, &ipv6_port)) {
          QUIC_DLOG(ERROR) << "Failed to parse preferred address IPs and ports";
          return false;
        }
        TransportParameters::PreferredAddress preferred_address;
        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()) {
          QUIC_DLOG(ERROR) << "Received preferred addresses of bad families "
                           << preferred_address;
          return false;
        }
        CBS connection_id_cbs;
        if (!CBS_get_u8_length_prefixed(&value, &connection_id_cbs)) {
          QUIC_DLOG(ERROR)
              << "Failed to parse length of preferred address connection ID";
          return false;
        }
        const size_t connection_id_length = CBS_len(&connection_id_cbs);
        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
                connection_id_length, version.transport_version)) {
          QUIC_DLOG(ERROR) << "Received preferred address connection ID of "
                           << "invalid length " << connection_id_length;
          return false;
        }
        preferred_address.connection_id.set_length(
            static_cast<uint8_t>(connection_id_length));
        if (preferred_address.connection_id.length() > 0 &&
            !CBS_copy_bytes(&connection_id_cbs,
                            reinterpret_cast<uint8_t*>(
                                preferred_address.connection_id.mutable_data()),
                            preferred_address.connection_id.length())) {
          QUIC_DLOG(ERROR) << "Failed to read preferred address connection ID";
          return false;
        }
        if (CBS_len(&value) != kStatelessResetTokenLength) {
          QUIC_DLOG(ERROR) << "Received preferred address with "
                           << "invalid remaining length " << CBS_len(&value);
          return false;
        }
        preferred_address.stateless_reset_token.assign(
            CBS_data(&value), CBS_data(&value) + CBS_len(&value));
        out->preferred_address =
            QuicMakeUnique<TransportParameters::PreferredAddress>(
                preferred_address);
      } break;
      case TransportParameters::kActiveConnectionIdLimit:
        parse_success = out->active_connection_id_limit.ReadFromCbs(&value);
        break;
      case TransportParameters::kGoogleQuicParam: {
        if (out->google_quic_params) {
          QUIC_DLOG(ERROR) << "Received a second Google parameter";
          return false;
        }
        QuicStringPiece serialized_params(
            reinterpret_cast<const char*>(CBS_data(&value)), CBS_len(&value));
        out->google_quic_params = CryptoFramer::ParseMessage(serialized_params);
      } break;
      case TransportParameters::kGoogleQuicVersion: {
        if (!CBS_get_u32(&value, &out->version)) {
          QUIC_DLOG(ERROR) << "Failed to parse Google version extension";
          return false;
        }
        if (perspective == Perspective::IS_SERVER) {
          CBS versions;
          if (!CBS_get_u8_length_prefixed(&value, &versions) ||
              CBS_len(&versions) % 4 != 0) {
            QUIC_DLOG(ERROR)
                << "Failed to parse Google supported versions length";
            return false;
          }
          while (CBS_len(&versions) > 0) {
            QuicVersionLabel version;
            if (!CBS_get_u32(&versions, &version)) {
              QUIC_DLOG(ERROR) << "Failed to parse Google supported version";
              return false;
            }
            out->supported_versions.push_back(version);
          }
        }
      } break;
    }
    if (!parse_success) {
      return false;
    }
  }

  const bool ok = out->AreValid();
  if (ok) {
    QUIC_DLOG(INFO) << "Parsed transport parameters " << *out << " from "
                    << in_len << " bytes";
  } else {
    QUIC_DLOG(ERROR) << "Transport parameter validity check failed " << *out
                     << " from " << in_len << " bytes";
  }
  return ok;
}

}  // namespace quic
