// 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.

#ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
#define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_

#include <netinet/icmp6.h>
#include <netinet/ip6.h>

#include "absl/strings/string_view.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_ip_address.h"

namespace quic {

enum : size_t {
  kIPv6HeaderSize = 40,
  kICMPv6HeaderSize = sizeof(icmp6_hdr),
  kTotalICMPv6HeaderSize = kIPv6HeaderSize + kICMPv6HeaderSize,
};

// QBONE packet processor accepts packets destined in either direction
// (client-to-network or network-to-client).  It inspects them and makes
// decisions on whether they should be forwarded or dropped, replying with ICMP
// messages as appropriate.
class QbonePacketProcessor {
 public:
  enum class Direction {
    // Packet is going from the QBONE client into the network behind the QBONE.
    FROM_OFF_NETWORK = 0,
    // Packet is going from the network begin QBONE to the client.
    FROM_NETWORK = 1
  };

  enum class ProcessingResult {
    OK = 0,
    SILENT_DROP = 1,
    ICMP = 2,
    // Equivalent to |SILENT_DROP| at the moment, but indicates that the
    // downstream filter has buffered the packet and deferred its processing.
    // The packet may be emitted at a later time.
    DEFER = 3,
    // In addition to sending an ICMP message, also send a TCP RST. This option
    // requires the incoming packet to have been a valid TCP packet, as a TCP
    // RST requires information from the current connection state to be
    // well-formed.
    ICMP_AND_TCP_RESET = 4,
    // Send a TCP RST.
    TCP_RESET = 5,
  };

  class OutputInterface {
   public:
    virtual ~OutputInterface();

    virtual void SendPacketToClient(absl::string_view packet) = 0;
    virtual void SendPacketToNetwork(absl::string_view packet) = 0;
  };

  class StatsInterface {
   public:
    virtual ~StatsInterface();

    virtual void OnPacketForwarded(Direction direction) = 0;
    virtual void OnPacketDroppedSilently(Direction direction) = 0;
    virtual void OnPacketDroppedWithIcmp(Direction direction) = 0;
    virtual void OnPacketDroppedWithTcpReset(Direction direction) = 0;
    virtual void OnPacketDeferred(Direction direction) = 0;
  };

  // Allows to implement a custom packet filter on top of the filtering done by
  // the packet processor itself.
  class Filter {
   public:
    virtual ~Filter();
    // The main interface function.  The following arguments are supplied:
    // - |direction|, to indicate direction of the packet.
    // - |full_packet|, which includes the IPv6 header and possibly the IPv6
    //   options that were understood by the processor.
    // - |payload|, the contents of the IPv6 packet, i.e. a TCP, a UDP or an
    //   ICMP packet.
    // - |icmp_header|, an output argument which allows the filter to specify
    //   the ICMP message with which the packet is to be rejected.
    // The method is called only on packets which were already verified as valid
    // IPv6 packets.
    //
    // The implementer of this method has four options to return:
    // - OK will cause the filter to pass the packet through
    // - SILENT_DROP will cause the filter to drop the packet silently
    // - ICMP will cause the filter to drop the packet and send an ICMP
    //   response.
    // - DEFER will cause the packet to be not forwarded; the filter is
    //   responsible for sending (or not sending) it later using |output|.
    //
    // Note that |output| should not be used except in the DEFER case, as the
    // processor will perform the necessary writes itself.
    virtual ProcessingResult FilterPacket(Direction direction,
                                          absl::string_view full_packet,
                                          absl::string_view payload,
                                          icmp6_hdr* icmp_header,
                                          OutputInterface* output);

   protected:
    // Helper methods that allow to easily extract information that is required
    // for filtering from the |ipv6_header| argument.  All of those assume that
    // the header is of valid size, which is true for everything passed into
    // FilterPacket().
    uint8_t TransportProtocolFromHeader(absl::string_view ipv6_header) {
      return ipv6_header[6];
    }
    QuicIpAddress SourceIpFromHeader(absl::string_view ipv6_header) {
      QuicIpAddress address;
      address.FromPackedString(&ipv6_header[8],
                               QuicIpAddress::kIPv6AddressSize);
      return address;
    }
    QuicIpAddress DestinationIpFromHeader(absl::string_view ipv6_header) {
      QuicIpAddress address;
      address.FromPackedString(&ipv6_header[24],
                               QuicIpAddress::kIPv6AddressSize);
      return address;
    }
  };

  // |self_ip| is the IP address from which the processor will originate ICMP
  // messages.  |client_ip| is the expected IP address of the client, used for
  // packet validation.
  //
  // |output| and |stats| are the visitor interfaces used by the processor.
  // |output| gets notified whenever the processor decides to send a packet, and
  // |stats| gets notified about any decisions that processor makes, without a
  // reference to which packet that decision was made about.
  QbonePacketProcessor(QuicIpAddress self_ip, QuicIpAddress client_ip,
                       size_t client_ip_subnet_length, OutputInterface* output,
                       StatsInterface* stats);
  QbonePacketProcessor(const QbonePacketProcessor&) = delete;
  QbonePacketProcessor& operator=(const QbonePacketProcessor&) = delete;

  // Accepts an IPv6 packet and handles it accordingly by either forwarding it,
  // replying with an ICMP packet or silently dropping it.  |packet| will be
  // modified in the process, by having the TTL field decreased.
  void ProcessPacket(std::string* packet, Direction direction);

  void set_filter(std::unique_ptr<Filter> filter) {
    filter_ = std::move(filter);
  }

  void set_client_ip(QuicIpAddress client_ip) { client_ip_ = client_ip; }
  void set_client_ip_subnet_length(size_t client_ip_subnet_length) {
    client_ip_subnet_length_ = client_ip_subnet_length;
  }

  static const QuicIpAddress kInvalidIpAddress;

 protected:
  // Processes the header and returns what should be done with the packet.
  // After that, calls an external packet filter if registered.  TTL of the
  // packet may be decreased in the process.
  ProcessingResult ProcessIPv6HeaderAndFilter(std::string* packet,
                                              Direction direction,
                                              uint8_t* transport_protocol,
                                              char** transport_data,
                                              icmp6_hdr* icmp_header);

  void SendIcmpResponse(icmp6_hdr* icmp_header,
                        absl::string_view original_packet,
                        Direction original_direction);

  void SendTcpReset(absl::string_view original_packet,
                    Direction original_direction);

  bool IsValid() const { return client_ip_ != kInvalidIpAddress; }

  // IP address of the server.  Used to send ICMP messages.
  in6_addr self_ip_;
  // IP address range of the VPN client.
  QuicIpAddress client_ip_;
  size_t client_ip_subnet_length_;

  OutputInterface* output_;
  StatsInterface* stats_;
  std::unique_ptr<Filter> filter_;

 private:
  // Performs basic sanity and permission checks on the packet, and decreases
  // the TTL.
  ProcessingResult ProcessIPv6Header(std::string* packet, Direction direction,
                                     uint8_t* transport_protocol,
                                     char** transport_data,
                                     icmp6_hdr* icmp_header);

  void SendResponse(Direction original_direction, absl::string_view packet);
};

}  // namespace quic
#endif  // QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
