// 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 "quic/core/quic_legacy_version_encapsulator.h"
#include "quic/core/crypto/crypto_handshake_message.h"
#include "quic/core/crypto/crypto_protocol.h"
#include "quic/core/quic_utils.h"
#include "quic/platform/api/quic_bug_tracker.h"

namespace quic {

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

QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {}

// static
QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead(
    absl::string_view 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(quic_bug_10615_1) << "OnSerializedPacket called twice";
    return;
  }
  if (serialized_packet.encrypted_length == 0) {
    unrecoverable_failure_encountered_ = true;
    QUIC_BUG(quic_bug_10615_2) << "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(quic_bug_10615_3) << "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(
    absl::string_view sni,
    absl::string_view 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();
  QUICHE_DCHECK(!LegacyVersionForEncapsulation().UsesCryptoFrames());
  QUICHE_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(quic_bug_10615_4)
        << "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(quic_bug_10615_5)
        << "Failed to perform Legacy Version Encapsulation of "
        << inner_packet.length() << " bytes";
    return 0;
  }
  if (encrypted_length > kMaxOutgoingPacketSize) {
    QUIC_BUG(quic_bug_10615_6)
        << "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
