// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h"
#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"

namespace quic {

QuicLegacyVersionEncapsulator::QuicLegacyVersionEncapsulator(
    QuicPacketBuffer packet_buffer)
    : packet_buffer_(packet_buffer) {}

QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {}

// static
QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead(
    quiche::QuicheStringPiece sni) {
  // The number 52 is the sum of:
  // - Flags (1 byte)
  // - Server Connection ID (8 bytes)
  // - Version (4 bytes)
  // - Packet Number (1 byte)
  // - Message Authentication Hash (12 bytes)
  // - Frame Type (1 byte)
  // - Stream ID (1 byte)
  // - ClientHello tag (4 bytes)
  // - ClientHello num tags (2 bytes)
  // - Padding (2 bytes)
  // - SNI tag (4 bytes)
  // - SNI end offset (4 bytes)
  // - QLVE tag (4 bytes)
  // - QLVE end offset (4 bytes)
  return 52 + sni.length();
}

QuicPacketBuffer QuicLegacyVersionEncapsulator::GetPacketBuffer() {
  return packet_buffer_;
}

void QuicLegacyVersionEncapsulator::OnSerializedPacket(
    SerializedPacket serialized_packet) {
  if (encrypted_length_ != 0) {
    unrecoverable_failure_encountered_ = true;
    QUIC_BUG << "OnSerializedPacket called twice";
    return;
  }
  if (serialized_packet.encrypted_length == 0) {
    unrecoverable_failure_encountered_ = true;
    QUIC_BUG << "OnSerializedPacket called with empty packet";
    return;
  }
  encrypted_length_ = serialized_packet.encrypted_length;
}

void QuicLegacyVersionEncapsulator::OnUnrecoverableError(
    QuicErrorCode error,
    const std::string& error_details) {
  unrecoverable_failure_encountered_ = true;
  QUIC_BUG << "QuicLegacyVersionEncapsulator received error " << error << ": "
           << error_details;
}

bool QuicLegacyVersionEncapsulator::ShouldGeneratePacket(
    HasRetransmittableData /*retransmittable*/,
    IsHandshake /*handshake*/) {
  return true;
}

const QuicFrames
QuicLegacyVersionEncapsulator::MaybeBundleAckOpportunistically() {
  // We do not want to ever include any ACKs here, return an empty array.
  return QuicFrames();
}

SerializedPacketFate QuicLegacyVersionEncapsulator::GetSerializedPacketFate(
    bool /*is_mtu_discovery*/,
    EncryptionLevel /*encryption_level*/) {
  return SEND_TO_WRITER;
}

// static
QuicPacketLength QuicLegacyVersionEncapsulator::Encapsulate(
    quiche::QuicheStringPiece sni,
    quiche::QuicheStringPiece inner_packet,
    const QuicConnectionId& server_connection_id,
    QuicTime creation_time,
    QuicByteCount outer_max_packet_length,
    char* out) {
  if (outer_max_packet_length > kMaxOutgoingPacketSize) {
    outer_max_packet_length = kMaxOutgoingPacketSize;
  }
  CryptoHandshakeMessage outer_chlo;
  outer_chlo.set_tag(kCHLO);
  outer_chlo.SetStringPiece(kSNI, sni);
  outer_chlo.SetStringPiece(kQLVE, inner_packet);
  const QuicData& serialized_outer_chlo = outer_chlo.GetSerialized();
  DCHECK(!LegacyVersionForEncapsulation().UsesCryptoFrames());
  DCHECK(LegacyVersionForEncapsulation().UsesQuicCrypto());
  QuicStreamFrame outer_stream_frame(
      QuicUtils::GetCryptoStreamId(
          LegacyVersionForEncapsulation().transport_version),
      /*fin=*/false,
      /*offset=*/0, serialized_outer_chlo.AsStringPiece());
  QuicFramer outer_framer(
      ParsedQuicVersionVector{LegacyVersionForEncapsulation()}, creation_time,
      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
  outer_framer.SetInitialObfuscators(server_connection_id);
  char outer_encrypted_packet[kMaxOutgoingPacketSize];
  QuicPacketBuffer outer_packet_buffer(outer_encrypted_packet, nullptr);
  QuicLegacyVersionEncapsulator creator_delegate(outer_packet_buffer);
  QuicPacketCreator outer_creator(server_connection_id, &outer_framer,
                                  &creator_delegate);
  outer_creator.SetMaxPacketLength(outer_max_packet_length);
  outer_creator.set_encryption_level(ENCRYPTION_INITIAL);
  outer_creator.SetTransmissionType(NOT_RETRANSMISSION);
  if (!outer_creator.AddPaddedSavedFrame(QuicFrame(outer_stream_frame),
                                         NOT_RETRANSMISSION)) {
    QUIC_BUG << "Failed to add Legacy Version Encapsulation stream frame "
                "(max packet length is "
             << outer_creator.max_packet_length() << ") " << outer_stream_frame;
    return 0;
  }
  outer_creator.FlushCurrentPacket();
  const QuicPacketLength encrypted_length = creator_delegate.encrypted_length_;
  if (creator_delegate.unrecoverable_failure_encountered_ ||
      encrypted_length == 0) {
    QUIC_BUG << "Failed to perform Legacy Version Encapsulation of "
             << inner_packet.length() << " bytes";
    return 0;
  }
  if (encrypted_length > kMaxOutgoingPacketSize) {
    QUIC_BUG << "Legacy Version Encapsulation outer creator generated a "
                "packet with unexpected length "
             << encrypted_length;
    return 0;
  }

  QUIC_DLOG(INFO) << "Successfully performed Legacy Version Encapsulation from "
                  << inner_packet.length() << " bytes to " << encrypted_length;

  // Replace our current packet with the encapsulated one.
  memcpy(out, outer_encrypted_packet, encrypted_length);
  return encrypted_length;
}

}  // namespace quic
