// Copyright 2017 The Fuchsia 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 "garnet/bin/mdns/service/mdns_interface_transceiver.h"

#include <iostream>

#include <arpa/inet.h>
#include <errno.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <poll.h>
#include <sys/socket.h>

#include "garnet/bin/mdns/service/dns_formatting.h"
#include "garnet/bin/mdns/service/dns_reading.h"
#include "garnet/bin/mdns/service/dns_writing.h"
#include "garnet/bin/mdns/service/mdns_addresses.h"
#include "garnet/bin/mdns/service/mdns_interface_transceiver_v4.h"
#include "garnet/bin/mdns/service/mdns_interface_transceiver_v6.h"
#include "lib/fostr/hex_dump.h"
#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/time/time_delta.h"

namespace mdns {

// static
std::unique_ptr<MdnsInterfaceTransceiver> MdnsInterfaceTransceiver::Create(
    inet::IpAddress address, const std::string& name, uint32_t index) {
  if (address.is_v4()) {
    return std::make_unique<MdnsInterfaceTransceiverV4>(address, name, index);
  } else {
    return std::make_unique<MdnsInterfaceTransceiverV6>(address, name, index);
  }
}

MdnsInterfaceTransceiver::MdnsInterfaceTransceiver(inet::IpAddress address,
                                                   const std::string& name,
                                                   uint32_t index)
    : address_(address),
      name_(name),
      index_(index),
      inbound_buffer_(kMaxPacketSize),
      outbound_buffer_(kMaxPacketSize) {}

MdnsInterfaceTransceiver::~MdnsInterfaceTransceiver() {}

bool MdnsInterfaceTransceiver::Start(InboundMessageCallback callback) {
  FXL_DCHECK(callback);
  FXL_DCHECK(!socket_fd_.is_valid()) << "Start called when already started.";

  std::cerr << "Starting mDNS on interface " << name_ << " " << address_
            << "\n";

  socket_fd_ = fxl::UniqueFD(socket(address_.family(), SOCK_DGRAM, 0));

  if (!socket_fd_.is_valid()) {
    FXL_LOG(ERROR) << "Failed to open socket, errno " << errno;
    return false;
  }

  // Set socket options and bind.
  if (SetOptionSharePort() != 0 || SetOptionJoinMulticastGroup() != 0 ||
      SetOptionOutboundInterface() != 0 || SetOptionUnicastTtl() != 0 ||
      SetOptionMulticastTtl() != 0 || SetOptionFamilySpecific() != 0 ||
      Bind() != 0) {
    socket_fd_.reset();
    return false;
  }

  inbound_message_callback_ = std::move(callback);

  WaitForInbound();
  return true;
}

void MdnsInterfaceTransceiver::Stop() {
  FXL_DCHECK(socket_fd_.is_valid()) << "Stop called when stopped.";
  fd_waiter_.Cancel();
  socket_fd_.reset();
}

void MdnsInterfaceTransceiver::SetAlternateAddress(
    const inet::IpAddress& alternate_address) {
  FXL_DCHECK(alternate_address.family() != address_.family());

  alternate_address_ = alternate_address;
}

void MdnsInterfaceTransceiver::SendMessage(DnsMessage* message,
                                           const inet::SocketAddress& address) {
  FXL_DCHECK(message);
  FXL_DCHECK(address.is_valid());
  FXL_DCHECK(address.family() == address_.family() ||
             address == MdnsAddresses::kV4Multicast);

  FixUpAddresses(&message->answers_);
  FixUpAddresses(&message->authorities_);
  FixUpAddresses(&message->additionals_);
  message->UpdateCounts();

  PacketWriter writer(std::move(outbound_buffer_));
  writer << *message;
  size_t packet_size = writer.position();
  outbound_buffer_ = writer.GetPacket();

  ssize_t result = SendTo(outbound_buffer_.data(), packet_size, address);

  ++messages_sent_;
  bytes_sent_ += packet_size;

  if (result < 0) {
    FXL_LOG(ERROR) << "Failed to sendto, errno " << errno;
    return;
  }
}

void MdnsInterfaceTransceiver::SendAddress(const std::string& host_full_name) {
  DnsMessage message;
  message.answers_.push_back(GetAddressResource(host_full_name));

  SendMessage(&message, MdnsAddresses::kV4Multicast);
}

void MdnsInterfaceTransceiver::SendAddressGoodbye(
    const std::string& host_full_name) {
  DnsMessage message;
  // Not using |GetAddressResource| here, because we want to modify the ttl.
  message.answers_.push_back(MakeAddressResource(host_full_name, address_));
  message.answers_.back()->time_to_live_ = 0;

  SendMessage(&message, MdnsAddresses::kV4Multicast);
}

void MdnsInterfaceTransceiver::LogTraffic() {
  std::cout << "interface " << name_ << " " << address_ << "\n";
  std::cout << "    messages received:  " << messages_received_ << "\n";
  std::cout << "    bytes received:     " << bytes_received_ << "\n";
  std::cout << "    messages sent:      " << messages_sent_ << "\n";
  std::cout << "    bytes sent:         " << bytes_sent_ << "\n";
}

int MdnsInterfaceTransceiver::SetOptionSharePort() {
  int param = 1;
  int result = setsockopt(socket_fd_.get(), SOL_SOCKET, SO_REUSEADDR, &param,
                          sizeof(param));
  if (result < 0) {
    FXL_LOG(ERROR) << "Failed to set socket option SO_REUSEADDR, errno "
                   << errno;
    return result;
  }

  param = 1;
  result = setsockopt(socket_fd_.get(), SOL_SOCKET, SO_REUSEPORT, &param,
                      sizeof(param));
  if (result < 0) {
    FXL_LOG(ERROR) << "Failed to set socket option SO_REUSEPORT, errno "
                   << errno;
  }

  return result;
}

void MdnsInterfaceTransceiver::WaitForInbound() {
  fd_waiter_.Wait([this](zx_status_t status,
                         uint32_t events) { InboundReady(status, events); },
                  socket_fd_.get(), POLLIN);
}

void MdnsInterfaceTransceiver::InboundReady(zx_status_t status,
                                            uint32_t events) {
  sockaddr_storage source_address_storage;
  socklen_t source_address_length =
      address_.is_v4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
  ssize_t result =
      recvfrom(socket_fd_.get(), inbound_buffer_.data(), inbound_buffer_.size(),
               0, reinterpret_cast<sockaddr*>(&source_address_storage),
               &source_address_length);
  if (result < 0) {
    FXL_LOG(ERROR) << "Failed to recvfrom, errno " << errno;
    // Wait a bit before trying again to avoid spamming the log.
    async::PostDelayedTask(async_get_default_dispatcher(),
                           [this]() { WaitForInbound(); }, zx::sec(10));
    return;
  }

  ++messages_received_;
  bytes_received_ += result;

  ReplyAddress reply_address(source_address_storage, address_);

  if (reply_address.socket_address().address() == address_) {
    // This is an outgoing message that's bounced back to us. Drop it.
    WaitForInbound();
    return;
  }

  PacketReader reader(inbound_buffer_);
  reader.SetBytesRemaining(static_cast<size_t>(result));
  std::unique_ptr<DnsMessage> message = std::make_unique<DnsMessage>();
  reader >> *message.get();

  if (reader.complete()) {
    FXL_DCHECK(inbound_message_callback_);
    inbound_message_callback_(std::move(message), reply_address);
  } else {
    inbound_buffer_.resize(result);
    FXL_LOG(ERROR) << "Couldn't parse message from " << reply_address << ", "
                   << result << " bytes: " << fostr::HexDump(inbound_buffer_);
    inbound_buffer_.resize(kMaxPacketSize);
  }

  WaitForInbound();
}

std::shared_ptr<DnsResource> MdnsInterfaceTransceiver::GetAddressResource(
    const std::string& host_full_name) {
  FXL_DCHECK(address_.is_valid());

  if (!address_resource_ ||
      address_resource_->name_.dotted_string_ != host_full_name) {
    address_resource_ = MakeAddressResource(host_full_name, address_);
  }

  return address_resource_;
}

std::shared_ptr<DnsResource>
MdnsInterfaceTransceiver::GetAlternateAddressResource(
    const std::string& host_full_name) {
  FXL_DCHECK(alternate_address_.is_valid());

  if (!alternate_address_resource_ ||
      alternate_address_resource_->name_.dotted_string_ != host_full_name) {
    alternate_address_resource_ =
        MakeAddressResource(host_full_name, alternate_address_);
  }

  return alternate_address_resource_;
}

std::shared_ptr<DnsResource> MdnsInterfaceTransceiver::MakeAddressResource(
    const std::string& host_full_name, const inet::IpAddress& address) {
  std::shared_ptr<DnsResource> resource;

  if (address.is_v4()) {
    resource = std::make_shared<DnsResource>(host_full_name, DnsType::kA);
    resource->a_.address_.address_ = address;
  } else {
    resource = std::make_shared<DnsResource>(host_full_name, DnsType::kAaaa);
    resource->aaaa_.address_.address_ = address;
  }

  return resource;
}

void MdnsInterfaceTransceiver::FixUpAddresses(
    std::vector<std::shared_ptr<DnsResource>>* resources) {
  for (auto iter = resources->begin(); iter != resources->end(); ++iter) {
    // Agents shouldn't produce AAAA resources, just A resource placeholders.
    FXL_DCHECK((*iter)->type_ != DnsType::kAaaa);

    if ((*iter)->type_ == DnsType::kA) {
      auto name = (*iter)->name_.dotted_string_;
      *iter = GetAddressResource(name);

      if (alternate_address_.is_valid()) {
        // Insert the alternate address record after the first one.
        iter = resources->insert(++iter, GetAlternateAddressResource(name));
      }
    }
  }
}

}  // namespace mdns
