// 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) {
  connection->SetMaxPacketLength(1250);
}

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 >> 8;
  absl::string_view quic_packet;
  quiche::QuicheIpAddress server_ip;
  if (ip_version == 6) {
    if (!reader.Seek(5)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP IPv6 start";
      return;
    }
    uint8_t next_header = 0;
    if (!reader.ReadUInt8(&next_header)) {
      QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP next header";
      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);
      return;
    }
    if (!reader.Seek(1)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP hop limit";
      return;
    }
    absl::string_view source_ip;
    if (!reader.ReadBytes(&source_ip, 16)) {
      QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP source IPv6";
      return;
    }
    server_ip.FromPackedString(source_ip.data(), source_ip.length());
    if (!reader.Seek(16)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP destination IPv6";
      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);
      return;
    }
    if (!reader.Seek(8)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP IPv4 start";
      return;
    }
    uint8_t ip_proto = 0;
    if (!reader.ReadUInt8(&ip_proto)) {
      QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP ip_proto";
      return;
    }
    if (ip_proto != 17) {
      QUIC_DLOG(ERROR) << "Dropping CONNECT-IP packet with unexpected IP proto "
                       << static_cast<int>(ip_proto);
      return;
    }
    if (!reader.Seek(2)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP IP checksum";
      return;
    }
    absl::string_view source_ip;
    if (!reader.ReadBytes(&source_ip, 4)) {
      QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP source IPv4";
      return;
    }
    server_ip.FromPackedString(source_ip.data(), source_ip.length());
    if (!reader.Seek(4)) {
      QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP destination IPv4";
      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);
      return;
    }
  } else {
    QUIC_DLOG(ERROR) << "Dropping CONNECT-IP packet with unexpected IP version "
                     << static_cast<int>(ip_version);
    return;
  }
  // Parse UDP header.
  uint16_t server_port;
  if (!reader.ReadUInt16(&server_port)) {
    QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP source port";
    return;
  }
  if (!reader.Seek(2)) {
    QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP destination port";
    return;
  }
  uint16_t udp_length;
  if (!reader.ReadUInt16(&udp_length)) {
    QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP UDP length";
    return;
  }
  if (!reader.Seek(2)) {
    QUICHE_DLOG(ERROR) << "Failed to seek CONNECT-IP UDP checksum";
    return;
  }
  if (!reader.ReadBytes(&quic_packet, udp_length)) {
    QUICHE_DLOG(ERROR) << "Failed to read CONNECT-IP UDP payload";
    return;
  }
  if (!reader.IsDoneReading()) {
    QUICHE_DLOG(INFO)
        << "Received CONNECT-IP UDP packet with extra data after payload";
  }
  QUIC_DLOG(INFO) << "Received CONNECT-IP encapsulated packet of length "
                  << packet.size();
  QuicTime now = connection()->clock()->ApproximateNow();
  QuicReceivedPacket received_packet(quic_packet.data(), quic_packet.length(),
                                     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) {
  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*/) {
  return true;
}

bool MasqueEncapsulatedClientSession::OnRouteAdvertisementCapsule(
    const RouteAdvertisementCapsule& /*capsule*/) {
  return true;
}

}  // namespace quic
