// Copyright 2019 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/masque/masque_encapsulated_client_session.h"

#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_ip_address.h"

namespace quic {

MasqueEncapsulatedClientSession::MasqueEncapsulatedClientSession(
    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
    QuicConnection* connection, const QuicServerId& server_id,
    QuicCryptoClientConfig* crypto_config,
    QuicClientPushPromiseIndex* push_promise_index,
    MasqueClientSession* masque_client_session)
    : QuicSpdyClientSession(config, supported_versions, connection, server_id,
                            crypto_config, push_promise_index),
      masque_client_session_(masque_client_session) {}

void MasqueEncapsulatedClientSession::ProcessPacket(
    absl::string_view packet, QuicSocketAddress server_address) {
  QuicTime now = connection()->clock()->ApproximateNow();
  QuicReceivedPacket received_packet(packet.data(), packet.length(), now);
  connection()->ProcessUdpPacket(connection()->self_address(), server_address,
                                 received_packet);
}

void MasqueEncapsulatedClientSession::CloseConnection(
    QuicErrorCode error, const std::string& details,
    ConnectionCloseBehavior connection_close_behavior) {
  connection()->CloseConnection(error, details, connection_close_behavior);
}

void MasqueEncapsulatedClientSession::OnConnectionClosed(
    const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
  QuicSpdyClientSession::OnConnectionClosed(frame, source);
  masque_client_session_->CloseConnectUdpStream(this);
}

void MasqueEncapsulatedClientSession::ProcessIpPacket(
    absl::string_view packet) {
  quiche::QuicheDataReader reader(packet);
  uint8_t first_byte;
  if (!reader.ReadUInt8(&first_byte)) {
    QUIC_DLOG(ERROR) << "Dropping empty CONNECT-IP packet";
    return;
  }
  const uint8_t ip_version = first_byte >> 4;
  quiche::QuicheIpAddress server_ip;
  if (ip_version == 6) {
    if (!reader.Seek(5)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP IPv6 start"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    uint8_t next_header = 0;
    if (!reader.ReadUInt8(&next_header)) {
      QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP next header"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    if (next_header != 17) {
      // Note that this drops packets with IPv6 extension headers, since we
      // do not expect to see them in practice.
      QUIC_DLOG(ERROR)
          << "Dropping CONNECT-IP packet with unexpected next header "
          << static_cast<int>(next_header) << "\n"
          << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    if (!reader.Seek(1)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP hop limit"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    absl::string_view source_ip;
    if (!reader.ReadStringPiece(&source_ip, 16)) {
      QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP source IPv6"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    server_ip.FromPackedString(source_ip.data(), source_ip.length());
    if (!reader.Seek(16)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP destination IPv6"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
  } else if (ip_version == 4) {
    uint8_t ihl = first_byte & 0xF;
    if (ihl < 5) {
      QUICHE_DLOG(ERROR) << "Dropping CONNECT-IP packet with invalid IHL "
                         << static_cast<int>(ihl) << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    if (!reader.Seek(8)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP IPv4 start"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    uint8_t ip_proto = 0;
    if (!reader.ReadUInt8(&ip_proto)) {
      QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP ip_proto"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    if (ip_proto != 17) {
      QUIC_DLOG(ERROR) << "Dropping CONNECT-IP packet with unexpected IP proto "
                       << static_cast<int>(ip_proto) << "\n"
                       << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    if (!reader.Seek(2)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP IP checksum"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    absl::string_view source_ip;
    if (!reader.ReadStringPiece(&source_ip, 4)) {
      QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP source IPv4"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    server_ip.FromPackedString(source_ip.data(), source_ip.length());
    if (!reader.Seek(4)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP destination IPv4"
                         << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
    uint8_t ip_options_length = (ihl - 5) * 4;
    if (!reader.Seek(ip_options_length)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP IP options of length "
                         << static_cast<int>(ip_options_length) << "\n"
                         << quiche::QuicheTextUtils::HexDump(packet);
      return;
    }
  } else {
    QUIC_DLOG(ERROR) << "Dropping CONNECT-IP packet with unexpected IP version "
                     << static_cast<int>(ip_version) << "\n"
                     << quiche::QuicheTextUtils::HexDump(packet);
    return;
  }
  // Parse UDP header.
  uint16_t server_port;
  if (!reader.ReadUInt16(&server_port)) {
    QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP source port"
                       << "\n"
                       << quiche::QuicheTextUtils::HexDump(packet);
    return;
  }
  if (!reader.Seek(2)) {
    QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP destination port"
                       << "\n"
                       << quiche::QuicheTextUtils::HexDump(packet);
    return;
  }
  uint16_t udp_length;
  if (!reader.ReadUInt16(&udp_length)) {
    QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP UDP length"
                       << "\n"
                       << quiche::QuicheTextUtils::HexDump(packet);
    return;
  }
  if (udp_length < 8) {
    QUICHE_DLOG(ERROR) << "Dropping CONNECT-IP packet with invalid UDP length "
                       << udp_length << "\n"
                       << quiche::QuicheTextUtils::HexDump(packet);
    return;
  }
  if (!reader.Seek(2)) {
    QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP UDP checksum"
                       << "\n"
                       << quiche::QuicheTextUtils::HexDump(packet);
    return;
  }
  absl::string_view quic_packet;
  if (!reader.ReadStringPiece(&quic_packet, udp_length - 8)) {
    QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP UDP payload"
                       << "\n"
                       << quiche::QuicheTextUtils::HexDump(packet);
    return;
  }
  if (!reader.IsDoneReading()) {
    QUICHE_DLOG(INFO) << "Received CONNECT-IP UDP packet with "
                      << reader.BytesRemaining()
                      << " extra bytes after payload\n"
                      << quiche::QuicheTextUtils::HexDump(packet);
  }
  QUIC_DLOG(INFO) << "Received CONNECT-IP encapsulated packet of length "
                  << quic_packet.size();
  QuicTime now = connection()->clock()->ApproximateNow();
  QuicReceivedPacket received_packet(quic_packet.data(), quic_packet.size(),
                                     now);
  QuicSocketAddress server_address = QuicSocketAddress(server_ip, server_port);
  connection()->ProcessUdpPacket(connection()->self_address(), server_address,
                                 received_packet);
}

void MasqueEncapsulatedClientSession::CloseIpSession(
    const std::string& details) {
  connection()->CloseConnection(QUIC_CONNECTION_CANCELLED, details,
                                ConnectionCloseBehavior::SILENT_CLOSE);
}

bool MasqueEncapsulatedClientSession::OnAddressAssignCapsule(
    const AddressAssignCapsule& capsule) {
  QUIC_DLOG(INFO) << "Received capsule " << capsule.ToString();
  for (auto assigned_address : capsule.assigned_addresses) {
    if (assigned_address.ip_prefix.address().IsIPv4() &&
        !local_v4_address_.IsInitialized()) {
      QUIC_LOG(INFO)
          << "MasqueEncapsulatedClientSession saving local IPv4 address "
          << assigned_address.ip_prefix.address();
      local_v4_address_ = assigned_address.ip_prefix.address();
    } else if (assigned_address.ip_prefix.address().IsIPv6() &&
               !local_v6_address_.IsInitialized()) {
      QUIC_LOG(INFO)
          << "MasqueEncapsulatedClientSession saving local IPv6 address "
          << assigned_address.ip_prefix.address();
      local_v6_address_ = assigned_address.ip_prefix.address();
    }
  }
  return true;
}

bool MasqueEncapsulatedClientSession::OnAddressRequestCapsule(
    const AddressRequestCapsule& capsule) {
  QUIC_DLOG(INFO) << "Ignoring received capsule " << capsule.ToString();
  return true;
}

bool MasqueEncapsulatedClientSession::OnRouteAdvertisementCapsule(
    const RouteAdvertisementCapsule& capsule) {
  QUIC_DLOG(INFO) << "Ignoring received capsule " << capsule.ToString();
  return true;
}

}  // namespace quic
