// Copyright 2018 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 "shill/active_link_monitor.h"

#include <string>
#include <vector>

#include <base/bind.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_util.h>

#include "shill/connection.h"
#include "shill/device_info.h"
#include "shill/event_dispatcher.h"
#include "shill/logging.h"
#include "shill/metrics.h"
#include "shill/net/arp_client.h"
#include "shill/net/arp_packet.h"
#include "shill/net/io_handler_factory.h"
#include "shill/net/ip_address.h"
#include "shill/net/shill_time.h"

using base::Bind;
using base::Unretained;
using std::string;

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kLink;
static string ObjectID(Connection* c) { return c->interface_name(); }
}

const int ActiveLinkMonitor::kDefaultTestPeriodMilliseconds = 5000;
const int ActiveLinkMonitor::kFailureThreshold = 5;
const int ActiveLinkMonitor::kFastTestPeriodMilliseconds = 200;
const int ActiveLinkMonitor::kMaxResponseSampleFilterDepth = 5;
const int ActiveLinkMonitor::kUnicastReplyReliabilityThreshold = 10;

ActiveLinkMonitor::ActiveLinkMonitor(const ConnectionRefPtr& connection,
                                     EventDispatcher* dispatcher,
                                     Metrics* metrics,
                                     DeviceInfo* device_info,
                                     const FailureCallback& failure_callback,
                                     const SuccessCallback& success_callback)
    : connection_(connection),
      dispatcher_(dispatcher),
      metrics_(metrics),
      device_info_(device_info),
      failure_callback_(failure_callback),
      success_callback_(success_callback),
      // Connection is not provided when this is used as a mock for testing
      // purpose.
      arp_client_(
          new ArpClient(connection ? connection->interface_index() : 0)),
      test_period_milliseconds_(kDefaultTestPeriodMilliseconds),
      broadcast_failure_count_(0),
      unicast_failure_count_(0),
      broadcast_success_count_(0),
      unicast_success_count_(0),
      is_unicast_(false),
      gateway_supports_unicast_arp_(false),
      response_sample_count_(0),
      response_sample_bucket_(0),
      io_handler_factory_(IOHandlerFactory::GetInstance()),
      time_(Time::GetInstance()) {
}

ActiveLinkMonitor::~ActiveLinkMonitor() {
  Stop();
}

bool ActiveLinkMonitor::Start(int test_period) {
  SLOG(connection_.get(), 2) << "In " << __func__ << ".";
  StopMonitorCycle();
  return StartInternal(test_period);
}

void ActiveLinkMonitor::Stop() {
  SLOG(connection_.get(), 2) << "In " << __func__ << ".";
  // Stop current cycle.
  StopMonitorCycle();

  // Clear stats accumulated from previous monitor cycles.
  local_mac_address_.Clear();
  gateway_mac_address_.Clear();
  broadcast_success_count_ = 0;
  unicast_success_count_ = 0;
  broadcast_failure_count_ = 0;
  unicast_failure_count_ = 0;
  is_unicast_ = false;
  gateway_supports_unicast_arp_ = false;
  response_sample_bucket_ = 0;
  response_sample_count_ = 0;
}

int ActiveLinkMonitor::GetResponseTimeMilliseconds() const {
  return response_sample_count_ ?
      response_sample_bucket_ / response_sample_count_ : 0;
}

bool ActiveLinkMonitor::IsGatewayFound() const {
  return !gateway_mac_address_.IsZero();
}

bool ActiveLinkMonitor::StartInternal(int probe_period_milliseconds) {
  test_period_milliseconds_ = probe_period_milliseconds;
  if (test_period_milliseconds_ > kDefaultTestPeriodMilliseconds) {
    LOG(WARNING) << "Long test period; UMA stats will be truncated.";
  }

  if (!device_info_->GetMacAddress(
          connection_->interface_index(), &local_mac_address_)) {
    LOG(ERROR) << "Could not get local MAC address.";
    metrics_->NotifyLinkMonitorFailure(
        connection_->technology(),
        Metrics::kLinkMonitorMacAddressNotFound,
        0, 0, 0);
    Stop();
    return false;
  }

  if (!StartArpClient()) {
    LOG(ERROR) << "Failed to start ARP client.";
    metrics_->NotifyLinkMonitorFailure(
        connection_->technology(),
        Metrics::kLinkMonitorClientStartFailure,
        0, 0, 0);
    Stop();
    return false;
  }

  if (gateway_mac_address_.IsEmpty()) {
    gateway_mac_address_ = ByteString(local_mac_address_.GetLength());
  }
  send_request_callback_.Reset(
      Bind(&ActiveLinkMonitor::SendRequest, Unretained(this)));
  // Post a task to send ARP request instead of calling it synchronously, to
  // maintain consistent expectation in the case of send failures, which will
  // always invoke failure callback.
  dispatcher_->PostTask(FROM_HERE, send_request_callback_.callback());
  return true;
}

void ActiveLinkMonitor::StopMonitorCycle() {
  StopArpClient();
  send_request_callback_.Cancel();
  timerclear(&sent_request_at_);
}

void ActiveLinkMonitor::AddResponseTimeSample(int response_time_milliseconds) {
  SLOG(connection_.get(), 2) << "In " << __func__ << " with sample "
                             << response_time_milliseconds << ".";
  metrics_->NotifyLinkMonitorResponseTimeSampleAdded(
      connection_->technology(), response_time_milliseconds);
  response_sample_bucket_ += response_time_milliseconds;
  if (response_sample_count_ < kMaxResponseSampleFilterDepth) {
    ++response_sample_count_;
  } else {
    response_sample_bucket_ =
        response_sample_bucket_ * kMaxResponseSampleFilterDepth /
            (kMaxResponseSampleFilterDepth + 1);
  }
}

// static
string ActiveLinkMonitor::HardwareAddressToString(const ByteString& address) {
  std::vector<string> address_parts;
  for (size_t i = 0; i < address.GetLength(); ++i) {
    address_parts.push_back(
        base::StringPrintf("%02x", address.GetConstData()[i]));
  }
  return base::JoinString(address_parts, ":");
}

bool ActiveLinkMonitor::StartArpClient() {
  if (!arp_client_->StartReplyListener()) {
    return false;
  }
  SLOG(connection_.get(), 4) << "Created ARP client; listening on socket "
                             << arp_client_->socket() << ".";
  receive_response_handler_.reset(io_handler_factory_->CreateIOReadyHandler(
      arp_client_->socket(), IOHandler::kModeInput,
      Bind(&ActiveLinkMonitor::ReceiveResponse, Unretained(this))));
  return true;
}

void ActiveLinkMonitor::StopArpClient() {
  arp_client_->Stop();
  receive_response_handler_.reset();
}

bool ActiveLinkMonitor::AddMissedResponse() {
  SLOG(connection_.get(), 2) << "In " << __func__ << ".";
  AddResponseTimeSample(test_period_milliseconds_);

  if (is_unicast_) {
    if (gateway_supports_unicast_arp_) {
      ++unicast_failure_count_;
    }
    unicast_success_count_ = 0;
  } else {
    ++broadcast_failure_count_;
    broadcast_success_count_ = 0;
  }

  if (unicast_failure_count_ + broadcast_failure_count_ >= kFailureThreshold) {
    LOG(ERROR) << "Link monitor has reached the failure threshold with "
               << broadcast_failure_count_
               << " broadcast failures and "
               << unicast_failure_count_
               << " unicast failures.";
    failure_callback_.Run(Metrics::kLinkMonitorFailureThresholdReached,
                          broadcast_failure_count_,
                          unicast_failure_count_);
    Stop();
    return true;
  }
  is_unicast_ = !is_unicast_;
  return false;
}

void ActiveLinkMonitor::ReceiveResponse(int fd) {
  SLOG(connection_.get(), 2) << "In " << __func__ << ".";
  ArpPacket packet;
  ByteString sender;
  if (!arp_client_->ReceivePacket(&packet, &sender)) {
    return;
  }

  if (!packet.IsReply()) {
    SLOG(connection_.get(), 4) << "This is not a reply packet.  Ignoring.";
    return;
  }

  if (!connection_->local().address().Equals(
           packet.remote_ip_address().address())) {
    SLOG(connection_.get(), 4) << "Response is not for our IP address.";
    return;
  }

  if (!local_mac_address_.Equals(packet.remote_mac_address())) {
    SLOG(connection_.get(), 4) << "Response is not for our MAC address.";
    return;
  }

  if (!connection_->gateway().address().Equals(
           packet.local_ip_address().address())) {
    SLOG(connection_.get(), 4)
        << "Response is not from the gateway IP address.";
    return;
  }

  struct timeval now, elapsed_time;
  time_->GetTimeMonotonic(&now);
  timersub(&now, &sent_request_at_, &elapsed_time);

  AddResponseTimeSample(elapsed_time.tv_sec * 1000 +
                        elapsed_time.tv_usec / 1000);

  if (is_unicast_) {
    ++unicast_success_count_;
    unicast_failure_count_ = 0;
    if (unicast_success_count_ >= kUnicastReplyReliabilityThreshold) {
      SLOG_IF(Link, 2, !gateway_supports_unicast_arp_)
          << "Gateway is now considered a reliable unicast responder.  "
             "Unicast failures will now count.";
      gateway_supports_unicast_arp_ = true;
    }
  } else {
    ++broadcast_success_count_;
    broadcast_failure_count_ = 0;
  }

  if (!gateway_mac_address_.Equals(packet.local_mac_address())) {
    const ByteString& new_mac_address = packet.local_mac_address();
    if (!IsGatewayFound()) {
      SLOG(connection_.get(), 2) << "Found gateway at "
                                 << HardwareAddressToString(new_mac_address);
    } else {
      SLOG(connection_.get(), 2) << "Gateway MAC address changed.";
    }
    gateway_mac_address_ = new_mac_address;
  }

  is_unicast_ = !is_unicast_;

  // Stop the current cycle, and invoke the success callback. All the
  // accumulated stats regarding the gateway are not cleared.
  StopMonitorCycle();
  success_callback_.Run();
}

void ActiveLinkMonitor::SendRequest() {
  SLOG(connection_.get(), 2) << "In " << __func__ << ".";

  // Timeout waiting for ARP reply and exceed the failure threshold.
  if (timerisset(&sent_request_at_) && AddMissedResponse()) {
    return;
  }

  ByteString destination_mac_address(gateway_mac_address_.GetLength());
  if (!IsGatewayFound()) {
    // The remote MAC addess is set by convention to be all-zeroes in the
    // ARP header if not known.  The ArpClient will translate an all-zeroes
    // remote address into a send to the broadcast (all-ones) address in
    // the Ethernet frame header.
    SLOG_IF(Link, 2, is_unicast_) << "Sending broadcast since "
                                  << "gateway MAC is unknown";
    is_unicast_ = false;
  } else if (is_unicast_) {
    destination_mac_address = gateway_mac_address_;
  }

  ArpPacket request(connection_->local(), connection_->gateway(),
                    local_mac_address_, destination_mac_address);
  if (!arp_client_->TransmitRequest(request)) {
    LOG(ERROR) << "Failed to send ARP request.  Stopping.";
    failure_callback_.Run(Metrics::kLinkMonitorTransmitFailure,
                          broadcast_failure_count_,
                          unicast_failure_count_);
    Stop();
    return;
  }

  time_->GetTimeMonotonic(&sent_request_at_);

  dispatcher_->PostDelayedTask(FROM_HERE, send_request_callback_.callback(),
                               test_period_milliseconds_);
}

}  // namespace shill
