// 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/bonnet/icmp_reachable.h"

#include <netinet/ip6.h>

#include <string>

#include "absl/strings/string_view.h"
#include "quiche/quic/core/crypto/quic_random.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_mutex.h"
#include "quiche/quic/qbone/platform/icmp_packet.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_text_utils.h"

namespace quic {
namespace {

constexpr QuicSocketEventMask kEventMask =
    kSocketEventReadable | kSocketEventWritable;
constexpr size_t kMtu = 1280;

constexpr size_t kIPv6AddrSize = sizeof(in6_addr);

}  // namespace

const char kUnknownSource[] = "UNKNOWN";
const char kNoSource[] = "N/A";

IcmpReachable::IcmpReachable(QuicIpAddress source, QuicIpAddress destination,
                             QuicTime::Delta timeout, KernelInterface* kernel,
                             QuicEventLoop* event_loop, StatsInterface* stats)
    : timeout_(timeout),
      event_loop_(event_loop),
      clock_(event_loop->GetClock()),
      alarm_factory_(event_loop->CreateAlarmFactory()),
      cb_(this),
      alarm_(alarm_factory_->CreateAlarm(new AlarmCallback(this))),
      kernel_(kernel),
      stats_(stats),
      send_fd_(0),
      recv_fd_(0) {
  src_.sin6_family = AF_INET6;
  dst_.sin6_family = AF_INET6;

  memcpy(&src_.sin6_addr, source.ToPackedString().data(), kIPv6AddrSize);
  memcpy(&dst_.sin6_addr, destination.ToPackedString().data(), kIPv6AddrSize);
}

IcmpReachable::~IcmpReachable() {
  if (send_fd_ > 0) {
    kernel_->close(send_fd_);
  }
  if (recv_fd_ > 0) {
    bool success = event_loop_->UnregisterSocket(recv_fd_);
    QUICHE_DCHECK(success);

    kernel_->close(recv_fd_);
  }
}

bool IcmpReachable::Init() {
  send_fd_ = kernel_->socket(PF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW);
  if (send_fd_ < 0) {
    QUIC_LOG(ERROR) << "Unable to open socket: " << errno;
    return false;
  }

  if (kernel_->bind(send_fd_, reinterpret_cast<struct sockaddr*>(&src_),
                    sizeof(sockaddr_in6)) < 0) {
    QUIC_LOG(ERROR) << "Unable to bind socket: " << errno;
    return false;
  }

  recv_fd_ =
      kernel_->socket(PF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_ICMPV6);
  if (recv_fd_ < 0) {
    QUIC_LOG(ERROR) << "Unable to open socket: " << errno;
    return false;
  }

  if (kernel_->bind(recv_fd_, reinterpret_cast<struct sockaddr*>(&src_),
                    sizeof(sockaddr_in6)) < 0) {
    QUIC_LOG(ERROR) << "Unable to bind socket: " << errno;
    return false;
  }

  icmp6_filter filter;
  ICMP6_FILTER_SETBLOCKALL(&filter);
  ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filter);
  if (kernel_->setsockopt(recv_fd_, SOL_ICMPV6, ICMP6_FILTER, &filter,
                          sizeof(filter)) < 0) {
    QUIC_LOG(ERROR) << "Unable to set ICMP6 filter.";
    return false;
  }

  if (!event_loop_->RegisterSocket(recv_fd_, kEventMask, &cb_)) {
    QUIC_LOG(ERROR) << "Unable to register recv ICMP socket";
    return false;
  }
  alarm_->Set(clock_->Now());

  QuicWriterMutexLock mu(&header_lock_);
  icmp_header_.icmp6_type = ICMP6_ECHO_REQUEST;
  icmp_header_.icmp6_code = 0;

  QuicRandom::GetInstance()->RandBytes(&icmp_header_.icmp6_id,
                                       sizeof(uint16_t));

  return true;
}

bool IcmpReachable::OnEvent(int fd) {
  char buffer[kMtu];

  sockaddr_in6 source_addr{};
  socklen_t source_addr_len = sizeof(source_addr);

  ssize_t size = kernel_->recvfrom(fd, &buffer, kMtu, 0,
                                   reinterpret_cast<sockaddr*>(&source_addr),
                                   &source_addr_len);

  if (size < 0) {
    if (errno != EAGAIN && errno != EWOULDBLOCK) {
      stats_->OnReadError(errno);
    }
    return false;
  }

  QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(
      absl::string_view(buffer, size));

  auto* header = reinterpret_cast<const icmp6_hdr*>(&buffer);
  QuicWriterMutexLock mu(&header_lock_);
  if (header->icmp6_data32[0] != icmp_header_.icmp6_data32[0]) {
    QUIC_VLOG(2) << "Unexpected response. id: " << header->icmp6_id
                 << " seq: " << header->icmp6_seq
                 << " Expected id: " << icmp_header_.icmp6_id
                 << " seq: " << icmp_header_.icmp6_seq;
    return true;
  }
  end_ = clock_->Now();
  QUIC_VLOG(1) << "Received ping response in " << (end_ - start_);

  std::string source;
  QuicIpAddress source_ip;
  if (!source_ip.FromPackedString(
          reinterpret_cast<char*>(&source_addr.sin6_addr), sizeof(in6_addr))) {
    QUIC_LOG(WARNING) << "Unable to parse source address.";
    source = kUnknownSource;
  } else {
    source = source_ip.ToString();
  }
  stats_->OnEvent({Status::REACHABLE, end_ - start_, source});
  return true;
}

void IcmpReachable::OnAlarm() {
  QuicWriterMutexLock mu(&header_lock_);

  if (end_ < start_) {
    QUIC_VLOG(1) << "Timed out on sequence: " << icmp_header_.icmp6_seq;
    stats_->OnEvent({Status::UNREACHABLE, QuicTime::Delta::Zero(), kNoSource});
  }

  icmp_header_.icmp6_seq++;
  CreateIcmpPacket(src_.sin6_addr, dst_.sin6_addr, icmp_header_, "",
                   [this](absl::string_view packet) {
                     QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(packet);

                     ssize_t size = kernel_->sendto(
                         send_fd_, packet.data(), packet.size(), 0,
                         reinterpret_cast<struct sockaddr*>(&dst_),
                         sizeof(sockaddr_in6));

                     if (size < packet.size()) {
                       stats_->OnWriteError(errno);
                     }
                     start_ = clock_->Now();
                   });

  alarm_->Set(clock_->ApproximateNow() + timeout_);
}

absl::string_view IcmpReachable::StatusName(IcmpReachable::Status status) {
  switch (status) {
    case REACHABLE:
      return "REACHABLE";
    case UNREACHABLE:
      return "UNREACHABLE";
    default:
      return "UNKNOWN";
  }
}

void IcmpReachable::EpollCallback::OnSocketEvent(QuicEventLoop* event_loop,
                                                 SocketFd fd,
                                                 QuicSocketEventMask events) {
  bool can_read_more = reachable_->OnEvent(fd);
  if (can_read_more) {
    bool success =
        event_loop->ArtificiallyNotifyEvent(fd, kSocketEventReadable);
    QUICHE_DCHECK(success);
  }
}

}  // namespace quic
