// Copyright 2016 The Chromium OS 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 "arc-networkd/manager.h"

#include <arpa/inet.h>
#include <stdint.h>

#include <utility>

#include <base/bind.h>
#include <base/logging.h>
#include <base/message_loop/message_loop.h>
#include <brillo/minijail/minijail.h>

#include "arc-networkd/ipc.pb.h"

namespace {

const char kMdnsMcastAddress[] = "224.0.0.251";
const uint16_t kMdnsPort = 5353;
const char kSsdpMcastAddress[] = "239.255.255.250";
const uint16_t kSsdpPort = 1900;

const int kMaxRandomAddressTries = 3;

const char kUnprivilegedUser[] = "arc-networkd";
const uint64_t kManagerCapMask = CAP_TO_MASK(CAP_NET_RAW);

}  // namespace

namespace arc_networkd {

Manager::Manager(const Options& opt, std::unique_ptr<HelperProcess> ip_helper)
    : int_ifname_(opt.int_ifname), con_ifname_(opt.con_ifname) {
  ip_helper_ = std::move(ip_helper);
}

int Manager::OnInit() {
  // Run with minimal privileges.
  brillo::Minijail* m = brillo::Minijail::GetInstance();
  struct minijail* jail = m->New();

  // Most of these return void, but DropRoot() can fail if the user/group
  // does not exist.
  CHECK(m->DropRoot(jail, kUnprivilegedUser, kUnprivilegedUser));
  m->UseCapabilities(jail, kManagerCapMask);
  m->Enter(jail);
  m->Destroy(jail);

  // Handle subprocess lifecycle.
  process_reaper_.Register(this);
  process_reaper_.WatchForChild(FROM_HERE,
                                ip_helper_->pid(),
                                base::Bind(&Manager::OnSubprocessExited,
                                           weak_factory_.GetWeakPtr(),
                                           ip_helper_->pid()));

  // This needs to execute after DBusDaemon::OnInit() creates bus_.
  base::MessageLoopForIO::current()->PostTask(
      FROM_HERE,
      base::Bind(&Manager::InitialSetup, weak_factory_.GetWeakPtr()));

  return DBusDaemon::OnInit();
}

void Manager::InitialSetup() {
  shill_client_.reset(new ShillClient(std::move(bus_)));
  shill_client_->RegisterDefaultInterfaceChangedHandler(
      base::Bind(&Manager::OnDefaultInterfaceChanged,
                 weak_factory_.GetWeakPtr()));
}

void Manager::OnDefaultInterfaceChanged(const std::string& ifname) {
  ClearArcIp();
  neighbor_finder_.reset();

  lan_ifname_ = ifname;
  if (ifname.empty()) {
    LOG(INFO) << "Unbinding services";
    mdns_forwarder_.reset();
    ssdp_forwarder_.reset();
    router_finder_.reset();
  } else {
    LOG(INFO) << "Binding to interface " << ifname;
    mdns_forwarder_.reset(new MulticastForwarder());
    ssdp_forwarder_.reset(new MulticastForwarder());
    router_finder_.reset(new RouterFinder());

    mdns_forwarder_->Start(int_ifname_,
                           ifname,
                           kMdnsMcastAddress,
                           kMdnsPort,
                           /* allow_stateless */ true);
    ssdp_forwarder_->Start(int_ifname_,
                           ifname,
                           kSsdpMcastAddress,
                           kSsdpPort,
                           /* allow_stateless */ false);

    router_finder_->Start(ifname,
        base::Bind(&Manager::OnRouteFound, weak_factory_.GetWeakPtr()));
  }
}

void Manager::OnRouteFound(const struct in6_addr& prefix,
                           int prefix_len,
                           const struct in6_addr& router) {
  if (prefix_len == 64) {
    char buf[64];
    LOG(INFO) << "Found IPv6 network "
              << inet_ntop(AF_INET6, &prefix, buf, sizeof(buf))
              << "/" << prefix_len
              << " route "
              << inet_ntop(AF_INET6, &router, buf, sizeof(buf));

    memcpy(&random_address_, &prefix, sizeof(random_address_));
    random_address_prefix_len_ = prefix_len;
    random_address_tries_ = 0;

    ArcIpConfig::GenerateRandom(&random_address_,
                                random_address_prefix_len_);

    neighbor_finder_.reset(new NeighborFinder());
    neighbor_finder_->Check(lan_ifname_, random_address_,
                            base::Bind(&Manager::OnNeighborCheckResult,
                                       weak_factory_.GetWeakPtr()));
  } else {
    LOG(INFO) << "No IPv6 connectivity available";
  }
}

void Manager::OnNeighborCheckResult(bool found) {
  if (found) {
    if (++random_address_tries_ >= kMaxRandomAddressTries) {
      LOG(WARNING) << "Too many IP collisions, giving up.";
      return;
    }

    LOG(INFO) << "Detected IP collision, retrying with a new address";
    ArcIpConfig::GenerateRandom(&random_address_,
                                random_address_prefix_len_);
    neighbor_finder_->Check(lan_ifname_, random_address_,
                            base::Bind(&Manager::OnNeighborCheckResult,
                                       weak_factory_.GetWeakPtr()));
  } else {
    struct in6_addr router;

    if (!ArcIpConfig::GetV6Address(int_ifname_, &router)) {
      LOG(ERROR) << "Error reading link local address for "
                 << int_ifname_;
      return;
    }

    char buf[64];
    LOG(INFO) << "Setting IPv6 address "
              << inet_ntop(AF_INET6, &random_address_, buf, sizeof(buf))
              << "/128 route "
              << inet_ntop(AF_INET6, &router, buf, sizeof(buf));

    // Set up new ARC IPv6 address, NDP, and forwarding rules.
    IpHelperMessage outer_msg;
    SetArcIp* inner_msg = outer_msg.mutable_set_arc_ip();
    inner_msg->set_prefix(&random_address_, sizeof(struct in6_addr));
    inner_msg->set_prefix_len(128);
    inner_msg->set_router(&router, sizeof(struct in6_addr));
    inner_msg->set_lan_ifname(lan_ifname_);
    ip_helper_->SendMessage(outer_msg);
  }
}

void Manager::ClearArcIp() {
  IpHelperMessage msg;
  msg.set_clear_arc_ip(true);
  ip_helper_->SendMessage(msg);
}

void Manager::OnShutdown(int* exit_code) {
  ClearArcIp();
}

void Manager::OnSubprocessExited(pid_t pid, const siginfo_t& info) {
  LOG(FATAL) << "Subprocess " << pid << " exited unexpectedly";
}

}  // namespace arc_networkd
