// Copyright (c) 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/qbone/platform/tcp_packet.h"

#include <netinet/ip6.h>

#include "absl/base/optimization.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/qbone/platform/internet_checksum.h"
#include "quiche/common/quiche_endian.h"

namespace quic {
namespace {

constexpr size_t kIPv6AddressSize = sizeof(in6_addr);
constexpr size_t kTcpTtl = 64;

struct TCPv6Packet {
  ip6_hdr ip_header;
  tcphdr tcp_header;
};

struct TCPv6PseudoHeader {
  uint32_t payload_size{};
  uint8_t zeros[3] = {0, 0, 0};
  uint8_t next_header = IPPROTO_TCP;
};

}  // namespace

void CreateTcpResetPacket(absl::string_view original_packet,
                          const std::function<void(absl::string_view)>& cb) {
  // By the time this method is called, original_packet should be fairly
  // strongly validated. However, it's better to be more paranoid than not, so
  // here are a bunch of very obvious checks.
  if (ABSL_PREDICT_FALSE(original_packet.size() < sizeof(ip6_hdr))) {
    return;
  }
  auto* ip6_header = reinterpret_cast<const ip6_hdr*>(original_packet.data());
  if (ABSL_PREDICT_FALSE(ip6_header->ip6_vfc >> 4 != 6)) {
    return;
  }
  if (ABSL_PREDICT_FALSE(ip6_header->ip6_nxt != IPPROTO_TCP)) {
    return;
  }
  if (ABSL_PREDICT_FALSE(quiche::QuicheEndian::NetToHost16(
                             ip6_header->ip6_plen) < sizeof(tcphdr))) {
    return;
  }
  auto* tcp_header = reinterpret_cast<const tcphdr*>(ip6_header + 1);

  // Now that the original packet has been confirmed to be well-formed, it's
  // time to make the TCP RST packet.
  TCPv6Packet tcp_packet{};

  const size_t payload_size = sizeof(tcphdr);

  // Set version to 6.
  tcp_packet.ip_header.ip6_vfc = 0x6 << 4;
  // Set the payload size, protocol and TTL.
  tcp_packet.ip_header.ip6_plen =
      quiche::QuicheEndian::HostToNet16(payload_size);
  tcp_packet.ip_header.ip6_nxt = IPPROTO_TCP;
  tcp_packet.ip_header.ip6_hops = kTcpTtl;
  // Since the TCP RST is impersonating the endpoint, flip the source and
  // destination addresses from the original packet.
  tcp_packet.ip_header.ip6_src = ip6_header->ip6_dst;
  tcp_packet.ip_header.ip6_dst = ip6_header->ip6_src;

  // The same is true about the TCP ports
  tcp_packet.tcp_header.dest = tcp_header->source;
  tcp_packet.tcp_header.source = tcp_header->dest;

  // There are no extensions in this header, so size is trivial
  tcp_packet.tcp_header.doff = sizeof(tcphdr) >> 2;
  // Checksum is 0 before it is computed
  tcp_packet.tcp_header.check = 0;

  // Per RFC 793, TCP RST comes in one of 3 flavors:
  //
  // * connection CLOSED
  // * connection in non-synchronized state (LISTEN, SYN-SENT, SYN-RECEIVED)
  // * connection in synchronized state (ESTABLISHED, FIN-WAIT-1, etc.)
  //
  // QBONE is acting like a firewall, so the RFC text of interest is the CLOSED
  // state. Note, however, that it is possible for a connection to actually be
  // in the FIN-WAIT-1 state on the remote end, but the processing logic does
  // not change.
  tcp_packet.tcp_header.rst = 1;

  // If the incoming segment has an ACK field, the reset takes its sequence
  // number from the ACK field of the segment,
  if (tcp_header->ack) {
    tcp_packet.tcp_header.seq = tcp_header->ack_seq;
  } else {
    // Otherwise the reset has sequence number zero and the ACK field is set to
    // the sum of the sequence number and segment length of the incoming segment
    tcp_packet.tcp_header.ack = 1;
    tcp_packet.tcp_header.seq = 0;
    tcp_packet.tcp_header.ack_seq = quiche::QuicheEndian::HostToNet32(
        quiche::QuicheEndian::NetToHost32(tcp_header->seq) + 1);
  }

  TCPv6PseudoHeader pseudo_header{};
  pseudo_header.payload_size = quiche::QuicheEndian::HostToNet32(payload_size);

  InternetChecksum checksum;
  // Pseudoheader.
  checksum.Update(tcp_packet.ip_header.ip6_src.s6_addr, kIPv6AddressSize);
  checksum.Update(tcp_packet.ip_header.ip6_dst.s6_addr, kIPv6AddressSize);
  checksum.Update(reinterpret_cast<char*>(&pseudo_header),
                  sizeof(pseudo_header));
  // TCP header.
  checksum.Update(reinterpret_cast<const char*>(&tcp_packet.tcp_header),
                  sizeof(tcp_packet.tcp_header));
  // There is no body.
  tcp_packet.tcp_header.check = checksum.Value();

  const char* packet = reinterpret_cast<char*>(&tcp_packet);

  cb(absl::string_view(packet, sizeof(tcp_packet)));
}

}  // namespace quic
