// 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_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,

  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 kOriginalConnectionId:
      return "original_connection_id";
    case kIdleTimeout:
      return "idle_timeout";
    case kStatelessResetToken:
      return "stateless_reset_token";
    case kMaxPacketSize:
      return "max_packet_size";
    case kInitialMaxData:
      return "initial_max_data";
    case kInitialMaxStreamDataBidiLocal:
      return "initial_max_stream_data_bidi_local";
    case kInitialMaxStreamDataBidiRemote:
      return "initial_max_stream_data_bidi_remote";
    case kInitialMaxStreamDataUni:
      return "initial_max_stream_data_uni";
    case kInitialMaxStreamsBidi:
      return "initial_max_streams_bidi";
    case kInitialMaxStreamsUni:
      return "initial_max_streams_uni";
    case kAckDelayExponent:
      return "ack_delay_exponent";
    case kMaxAckDelay:
      return "max_ack_delay";
    case kDisableMigration:
      return "disable_migration";
    case kPreferredAddress:
      return "preferred_address";
    case kGoogleQuicParam:
      return "google";
    case 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();
  }
  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)
// 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();
  if (!ok) {
    QUIC_DLOG(ERROR) << "Invalid transport parameters " << *this;
  }
  return ok;
}

TransportParameters::~TransportParameters() = default;

bool SerializeTransportParameters(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, 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, 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)) {
    QUIC_BUG << "Failed to write integers for " << in;
    return false;
  }

  // disable_migration
  if (in.disable_migration) {
    if (!CBB_add_u16(&params, 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, 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, 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, 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(const uint8_t* in,
                              size_t in_len,
                              Perspective perspective,
                              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 kOriginalConnectionId:
        if (!out->original_connection_id.IsEmpty()) {
          QUIC_DLOG(ERROR) << "Received a second original connection ID";
          return false;
        }
        if (CBS_len(&value) > static_cast<size_t>(kQuicMaxConnectionIdLength)) {
          QUIC_DLOG(ERROR) << "Received original connection ID of "
                           << "invalid length " << CBS_len(&value);
          return false;
        }
        if (CBS_len(&value) != 0) {
          out->original_connection_id.set_length(CBS_len(&value));
          memcpy(out->original_connection_id.mutable_data(), CBS_data(&value),
                 CBS_len(&value));
        }
        break;
      case kIdleTimeout:
        parse_success = out->idle_timeout_milliseconds.ReadFromCbs(&value);
        break;
      case 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 kMaxPacketSize:
        parse_success = out->max_packet_size.ReadFromCbs(&value);
        break;
      case kInitialMaxData:
        parse_success = out->initial_max_data.ReadFromCbs(&value);
        break;
      case kInitialMaxStreamDataBidiLocal:
        parse_success =
            out->initial_max_stream_data_bidi_local.ReadFromCbs(&value);
        break;
      case kInitialMaxStreamDataBidiRemote:
        parse_success =
            out->initial_max_stream_data_bidi_remote.ReadFromCbs(&value);
        break;
      case kInitialMaxStreamDataUni:
        parse_success = out->initial_max_stream_data_uni.ReadFromCbs(&value);
        break;
      case kInitialMaxStreamsBidi:
        parse_success = out->initial_max_streams_bidi.ReadFromCbs(&value);
        break;
      case kInitialMaxStreamsUni:
        parse_success = out->initial_max_streams_uni.ReadFromCbs(&value);
        break;
      case kAckDelayExponent:
        parse_success = out->ack_delay_exponent.ReadFromCbs(&value);
        break;
      case kMaxAckDelay:
        parse_success = out->max_ack_delay.ReadFromCbs(&value);
        break;
      case 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 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;
        }
        if (CBS_len(&connection_id_cbs) > kQuicMaxConnectionIdLength) {
          QUIC_DLOG(ERROR) << "Bad preferred address connection ID length";
          return false;
        }
        preferred_address.connection_id.set_length(CBS_len(&connection_id_cbs));
        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 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 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
