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

#include <arpa/inet.h>
#include <netinet/icmp6.h>
#include <netinet/ip.h>

#include <base/time/default_tick_clock.h>

#include "shill/event_dispatcher.h"
#include "shill/logging.h"
#include "shill/net/byte_string.h"
#include "shill/net/io_handler_factory.h"
#include "shill/net/ip_address.h"
#include "shill/net/sockets.h"

namespace {
const int kIPHeaderLengthUnitBytes = 4;
}

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kWiFi;
static std::string ObjectID(const IcmpSession* i) {
  return "(icmp_session)";
}
}  // namespace Logging

uint16_t IcmpSession::kNextUniqueEchoId = 0;
const int IcmpSession::kTotalNumEchoRequests = 3;
const int IcmpSession::kEchoRequestIntervalSeconds = 1;  // default for ping
// We should not need more than 1 second after the last request is sent to
// receive the final reply.
const size_t IcmpSession::kTimeoutSeconds =
    kEchoRequestIntervalSeconds * kTotalNumEchoRequests + 1;

IcmpSession::IcmpSession(EventDispatcher* dispatcher)
    : weak_ptr_factory_(this),
      dispatcher_(dispatcher),
      io_handler_factory_(IOHandlerFactory::GetInstance()),
      icmp_(new Icmp()),
      echo_id_(kNextUniqueEchoId),
      current_sequence_number_(0),
      tick_clock_(&default_tick_clock_) {
  // Each IcmpSession will have a unique echo ID to identify requests and reply
  // messages.
  ++kNextUniqueEchoId;
}

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

bool IcmpSession::Start(const IPAddress& destination,
                        int interface_index,
                        const IcmpSessionResultCallback& result_callback) {
  if (!dispatcher_) {
    LOG(ERROR) << "Invalid dispatcher";
    return false;
  }
  if (IsStarted()) {
    LOG(WARNING) << "ICMP session already started";
    return false;
  }
  if (!icmp_->Start(destination, interface_index)) {
    return false;
  }
  echo_reply_handler_.reset(io_handler_factory_->CreateIOInputHandler(
      icmp_->socket(),
      Bind(&IcmpSession::OnEchoReplyReceived, weak_ptr_factory_.GetWeakPtr()),
      Bind(&IcmpSession::OnEchoReplyError, weak_ptr_factory_.GetWeakPtr())));
  result_callback_ = result_callback;
  timeout_callback_.Reset(Bind(&IcmpSession::ReportResultAndStopSession,
                               weak_ptr_factory_.GetWeakPtr()));
  dispatcher_->PostDelayedTask(FROM_HERE, timeout_callback_.callback(),
                               kTimeoutSeconds * 1000);
  seq_num_to_sent_recv_time_.clear();
  received_echo_reply_seq_numbers_.clear();
  dispatcher_->PostTask(FROM_HERE, Bind(&IcmpSession::TransmitEchoRequestTask,
                                        weak_ptr_factory_.GetWeakPtr()));

  return true;
}

void IcmpSession::Stop() {
  if (!IsStarted()) {
    return;
  }
  timeout_callback_.Cancel();
  echo_reply_handler_.reset();
  icmp_->Stop();
}

bool IcmpSession::IsStarted() const {
  return icmp_->IsStarted();
}

// static
bool IcmpSession::AnyRepliesReceived(const IcmpSessionResult& result) {
  for (const base::TimeDelta& latency : result) {
    if (!latency.is_zero()) {
      return true;
    }
  }
  return false;
}

// static
bool IcmpSession::IsPacketLossPercentageGreaterThan(
    const IcmpSessionResult& result, int percentage_threshold) {
  if (percentage_threshold < 0) {
    LOG(ERROR) << __func__ << ": negative percentage threshold ("
               << percentage_threshold << ")";
    return false;
  }

  if (result.empty()) {
    return false;
  }

  int lost_packet_count = 0;
  for (const base::TimeDelta& latency : result) {
    if (latency.is_zero()) {
      ++lost_packet_count;
    }
  }
  int packet_loss_percentage = (lost_packet_count * 100) / result.size();
  return packet_loss_percentage > percentage_threshold;
}

void IcmpSession::TransmitEchoRequestTask() {
  if (!IsStarted()) {
    // This might happen when ping times out or is stopped between two calls
    // to IcmpSession::TransmitEchoRequestTask.
    return;
  }
  if (icmp_->TransmitEchoRequest(echo_id_, current_sequence_number_)) {
    seq_num_to_sent_recv_time_[current_sequence_number_] =
        std::make_pair(tick_clock_->NowTicks(), base::TimeTicks());
  }
  ++current_sequence_number_;
  // If we fail to transmit the echo request, fall through instead of returning,
  // so we continue sending echo requests until |kTotalNumEchoRequests| echo
  // requests are sent.

  if (seq_num_to_sent_recv_time_.size() != kTotalNumEchoRequests) {
    dispatcher_->PostDelayedTask(FROM_HERE,
                                 Bind(&IcmpSession::TransmitEchoRequestTask,
                                      weak_ptr_factory_.GetWeakPtr()),
                                 kEchoRequestIntervalSeconds * 1000);
  }
}

int IcmpSession::OnV4EchoReplyReceived(InputData* data) {
  DCHECK_GE(data->len, 0);

  ByteString message(data->buf, data->len);
  if (message.GetLength() < sizeof(struct iphdr) + sizeof(struct icmphdr)) {
    LOG(WARNING) << "Received ICMP packet is too short to contain ICMP header";
    return -1;
  }

  const struct iphdr* received_ip_header =
      reinterpret_cast<const struct iphdr*>(message.GetConstData());
  const struct icmphdr* received_icmp_header =
      reinterpret_cast<const struct icmphdr*>(message.GetConstData() +
                                              received_ip_header->ihl *
                                                  kIPHeaderLengthUnitBytes);
  // We might have received other types of ICMP traffic, so ensure that the
  // message is an echo reply before handling it.
  if (received_icmp_header->type != ICMP_ECHOREPLY) {
    return -1;
  }

  // Make sure the message is valid and matches a pending echo request.
  if (received_icmp_header->code != Icmp::kIcmpEchoCode) {
    LOG(WARNING) << "ICMP header code is invalid";
    return -1;
  }

  if (received_icmp_header->un.echo.id != echo_id_) {
    SLOG(this, 3) << "received message echo id ("
                  << received_icmp_header->un.echo.id
                  << ") does not match this ICMP session's echo id ("
                  << echo_id_ << ")";
    return -1;
  }

  return received_icmp_header->un.echo.sequence;
}

int IcmpSession::OnV6EchoReplyReceived(InputData* data) {
  ByteString message(data->buf, data->len);
  if (message.GetLength() < sizeof(struct icmp6_hdr)) {
    LOG(WARNING)
        << "Received ICMP packet is too short to contain ICMPv6 header";
    return -1;
  }

  // Per RFC3542 section 3, ICMPv6 raw sockets do not contain the IP header
  // (unlike ICMPv4 raw sockets).
  const struct icmp6_hdr* received_icmp_header =
      reinterpret_cast<const struct icmp6_hdr*>(message.GetConstData());
  // We might have received other types of ICMP traffic, so ensure that the
  // message is an echo reply before handling it.
  if (received_icmp_header->icmp6_type != ICMP6_ECHO_REPLY) {
    return -1;
  }

  // Make sure the message is valid and matches a pending echo request.
  if (received_icmp_header->icmp6_code != Icmp::kIcmpEchoCode) {
    LOG(WARNING) << "ICMPv6 header code is invalid";
    return -1;
  }

  if (received_icmp_header->icmp6_id != echo_id_) {
    SLOG(this, 3) << "received message echo id ("
                  << received_icmp_header->icmp6_id
                  << ") does not match this ICMPv6 session's echo id ("
                  << echo_id_ << ")";
    return -1;
  }

  return received_icmp_header->icmp6_seq;
}

void IcmpSession::OnEchoReplyReceived(InputData* data) {
  DCHECK_GE(data->len, 0);

  int received_seq_num = -1;
  if (icmp_->destination().family() == IPAddress::kFamilyIPv4) {
    received_seq_num = OnV4EchoReplyReceived(data);
  } else if (icmp_->destination().family() == IPAddress::kFamilyIPv6) {
    received_seq_num = OnV6EchoReplyReceived(data);
  } else {
    NOTREACHED();
  }

  if (received_seq_num < 0) {
    // Could not parse reply.
    return;
  }

  if (received_echo_reply_seq_numbers_.find(received_seq_num) !=
      received_echo_reply_seq_numbers_.end()) {
    // Echo reply for this message already handled previously.
    return;
  }

  const auto& seq_num_to_sent_recv_time_pair =
      seq_num_to_sent_recv_time_.find(received_seq_num);
  if (seq_num_to_sent_recv_time_pair == seq_num_to_sent_recv_time_.end()) {
    // Echo reply not meant for any sent echo requests.
    return;
  }

  // Record the time that the echo reply was received.
  seq_num_to_sent_recv_time_pair->second.second = tick_clock_->NowTicks();
  received_echo_reply_seq_numbers_.insert(received_seq_num);

  if (received_echo_reply_seq_numbers_.size() == kTotalNumEchoRequests) {
    // All requests sent and replies received, so report results and end the
    // ICMP session.
    ReportResultAndStopSession();
  }
}

std::vector<base::TimeDelta> IcmpSession::GenerateIcmpResult() {
  std::vector<base::TimeDelta> latencies;
  for (const auto& seq_num_to_sent_recv_time_pair :
       seq_num_to_sent_recv_time_) {
    const SentRecvTimePair& sent_recv_timestamp_pair =
        seq_num_to_sent_recv_time_pair.second;
    if (sent_recv_timestamp_pair.second.is_null()) {
      // Invalid latency if an echo response has not been received.
      latencies.push_back(base::TimeDelta());
    } else {
      latencies.push_back(sent_recv_timestamp_pair.second -
                          sent_recv_timestamp_pair.first);
    }
  }
  return latencies;
}

void IcmpSession::OnEchoReplyError(const std::string& error_msg) {
  LOG(ERROR) << __func__ << ": " << error_msg;
  // Do nothing when we encounter an IO error, so we can continue receiving
  // other pending echo replies.
}

void IcmpSession::ReportResultAndStopSession() {
  if (!IsStarted()) {
    LOG(WARNING) << "ICMP session not started";
    return;
  }
  Stop();
  // Invoke result callback after calling IcmpSession::Stop, since the callback
  // might delete this object. (Any subsequent call to IcmpSession::Stop leads
  // to a segfault since this function belongs to the deleted object.)
  if (!result_callback_.is_null()) {
    result_callback_.Run(GenerateIcmpResult());
  }
}

}  // namespace shill
