//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#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/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(IcmpSession* i) { return "(icmp_session)"; }
}

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),
      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(dispatcher_->CreateInputHandler(
      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();
}

// 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.size() == 0) {
    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_.emplace(
        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
