// 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 "quic/core/quic_types.h"
#include "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_
