// Copyright 2016 The Chromium 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 "components/cronet/stale_host_resolver.h"

#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/dns/context_host_resolver.h"
#include "net/dns/dns_util.h"
#include "net/dns/host_resolver_source.h"
#include "net/log/net_log_with_source.h"

namespace cronet {

namespace {

// Used in histograms; do not modify existing values.
enum RequestOutcome {
  // Served from (valid) cache, hosts file, IP literal, etc.
  SYNCHRONOUS = 0,

  // Network responded; there was no usable stale data.
  NETWORK_WITHOUT_STALE = 1,

  // Network responded before stale delay; there was usable stale data.
  NETWORK_WITH_STALE = 2,

  // Stale data returned; network didn't respond before the stale delay.
  STALE_BEFORE_NETWORK = 3,

  // Request canceled; there was no usable stale data.
  CANCELED_WITHOUT_STALE = 4,

  // Request canceled; there was usable stale data.
  CANCELED_WITH_STALE = 5,

  // Stale data returned; network got ERR_NAME_NOT_RESOLVED.
  STALE_INSTEAD_OF_NETWORK_NAME_NOT_RESOLVED = 6,

  MAX_REQUEST_OUTCOME
};

void RecordRequestOutcome(RequestOutcome outcome) {
  UMA_HISTOGRAM_ENUMERATION("DNS.StaleHostResolver.RequestOutcome", outcome,
                            MAX_REQUEST_OUTCOME);
}

void RecordCacheSizes(size_t restored, size_t current) {
  UMA_HISTOGRAM_COUNTS_1000("DNS.StaleHostResolver.RestoreSizeOnCacheMiss",
                            restored);
  UMA_HISTOGRAM_COUNTS_1000("DNS.StaleHostResolver.SizeOnCacheMiss", current);
}

void RecordAddressListDelta(net::AddressListDeltaType delta) {
  UMA_HISTOGRAM_ENUMERATION("DNS.StaleHostResolver.StaleAddressListDelta",
                            delta, net::MAX_DELTA_TYPE);
}

void RecordTimeDelta(base::TimeTicks network_time, base::TimeTicks stale_time) {
  if (network_time <= stale_time) {
    UMA_HISTOGRAM_LONG_TIMES_100("DNS.StaleHostResolver.NetworkEarly",
                                 stale_time - network_time);
  } else {
    UMA_HISTOGRAM_LONG_TIMES_100("DNS.StaleHostResolver.NetworkLate",
                                 network_time - stale_time);
  }
}

}  // namespace

// A request made by the StaleHostResolver. May return fresh cached data,
// network data, or stale cached data.
class StaleHostResolver::RequestImpl
    : public net::HostResolver::ResolveHostRequest {
 public:
  // StaleOptions will be read directly from |resolver|.
  RequestImpl(base::WeakPtr<StaleHostResolver> resolver,
              const net::HostPortPair& host,
              const net::NetLogWithSource& net_log,
              const ResolveHostParameters& input_parameters,
              const base::TickClock* tick_clock);
  ~RequestImpl() override;

  // net::HostResolver::ResolveHostRequest implementation:
  int Start(net::CompletionOnceCallback result_callback) override;
  const base::Optional<net::AddressList>& GetAddressResults() const override;
  const base::Optional<std::vector<std::string>>& GetTextResults()
      const override;
  const base::Optional<std::vector<net::HostPortPair>>& GetHostnameResults()
      const override;
  const base::Optional<net::HostCache::EntryStaleness>& GetStaleInfo()
      const override;
  void ChangeRequestPriority(net::RequestPriority priority) override;

  // Called on completion of an asynchronous (network) inner request. Expected
  // to be called by StaleHostResolver::OnNetworkRequestComplete().
  void OnNetworkRequestComplete(int error);

 private:
  bool have_network_request() const { return network_request_ != nullptr; }
  bool have_cache_data() const {
    return cache_error_ != net::ERR_DNS_CACHE_MISS;
  }
  bool have_returned() const { return result_callback_.is_null(); }

  // Determines if |cache_error_| and |cache_request_| represents a usable entry
  // per the requirements of |resolver_->options_|.
  bool CacheDataIsUsable() const;

  // Callback for |stale_timer_| that returns stale results.
  void OnStaleDelayElapsed();

  // Logging for when the underlying resolve completes synchronously.
  void RecordSynchronousRequest();
  // Logging for when the overall result is determined on completion of
  // |network_request_|.
  void RecordNetworkRequest(
      int error,
      bool returned_stale_data_instead_of_network_name_not_resolved);
  // Logging for when |stale_timer_| fires and |stale_request_| is to be used as
  // the overall result.
  void RecordLateRequest();
  // Logging for when the request is cancelled after Start() is called and
  // before a result is returned.
  void RecordCanceledRequest();

  base::WeakPtr<StaleHostResolver> resolver_;

  const net::HostPortPair host_;
  const net::NetLogWithSource net_log_;
  const ResolveHostParameters input_parameters_;

  // The callback passed into |Start()| to be called when the request returns.
  net::CompletionOnceCallback result_callback_;

  // The error from the stale cache entry, if there was one.
  // If not, net::ERR_DNS_CACHE_MISS.
  int cache_error_;
  // Inner local-only/stale-allowed request.
  std::unique_ptr<ResolveHostRequest> cache_request_;
  // A timer that fires when the |Request| should return stale results, if the
  // underlying network request has not finished yet.
  base::OneShotTimer stale_timer_;

  // An inner request for network results. Only set if |cache_request_| gave a
  // stale or unusable result, and unset if the stale result is to be used as
  // the overall result.
  std::unique_ptr<ResolveHostRequest> network_request_;

  // Statistics used in histograms:
  // Number of HostCache entries that were restored from prefs, recorded at the
  // time the cache was checked.
  size_t restore_size_;
  // Current HostCache size at the time the cache was checked.
  size_t current_size_;

  base::WeakPtrFactory<RequestImpl> weak_ptr_factory_;
};

StaleHostResolver::RequestImpl::RequestImpl(
    base::WeakPtr<StaleHostResolver> resolver,
    const net::HostPortPair& host,
    const net::NetLogWithSource& net_log,
    const ResolveHostParameters& input_parameters,
    const base::TickClock* tick_clock)
    : resolver_(std::move(resolver)),
      host_(host),
      net_log_(net_log),
      input_parameters_(input_parameters),
      cache_error_(net::ERR_DNS_CACHE_MISS),
      stale_timer_(tick_clock),
      restore_size_(0),
      current_size_(0),
      weak_ptr_factory_(this) {
  DCHECK(resolver_);
}

StaleHostResolver::RequestImpl::~RequestImpl() {
  if (!have_returned())
    RecordCanceledRequest();
}

int StaleHostResolver::RequestImpl::Start(
    net::CompletionOnceCallback result_callback) {
  DCHECK(resolver_);
  DCHECK(!result_callback.is_null());

  restore_size_ = resolver_->inner_resolver_->LastRestoredCacheSize();
  current_size_ = resolver_->inner_resolver_->CacheSize();

  net::HostResolver::ResolveHostParameters cache_parameters = input_parameters_;
  cache_parameters.cache_usage =
      net::HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
  cache_parameters.source = net::HostResolverSource::LOCAL_ONLY;
  cache_request_ = resolver_->inner_resolver_->CreateRequest(host_, net_log_,
                                                             cache_parameters);
  cache_error_ =
      cache_request_->Start(base::BindOnce([](int error) { NOTREACHED(); }));
  DCHECK_NE(net::ERR_IO_PENDING, cache_error_);
  // If it's a fresh cache hit (or literal), return it synchronously.
  if (cache_error_ != net::ERR_DNS_CACHE_MISS &&
      (!cache_request_->GetStaleInfo() ||
       !cache_request_->GetStaleInfo().value().is_stale())) {
    RecordSynchronousRequest();
    return cache_error_;
  }

  result_callback_ = std::move(result_callback);

  if (CacheDataIsUsable()) {
    // |stale_timer_| is deleted when the Request is deleted, so it's safe to
    // use Unretained here.
    base::Callback<void()> stale_callback =
        base::Bind(&StaleHostResolver::RequestImpl::OnStaleDelayElapsed,
                   base::Unretained(this));
    stale_timer_.Start(FROM_HERE, resolver_->options_.delay, stale_callback);
  } else {
    cache_error_ = net::ERR_DNS_CACHE_MISS;
    cache_request_.reset();
  }

  // Don't check the cache again.
  net::HostResolver::ResolveHostParameters no_cache_parameters =
      input_parameters_;
  no_cache_parameters.cache_usage =
      net::HostResolver::ResolveHostParameters::CacheUsage::DISALLOWED;
  network_request_ = resolver_->inner_resolver_->CreateRequest(
      host_, net_log_, no_cache_parameters);
  int network_rv = network_request_->Start(
      base::BindOnce(&StaleHostResolver::OnNetworkRequestComplete, resolver_,
                     network_request_.get(), weak_ptr_factory_.GetWeakPtr()));

  // Network resolver has returned synchronously (for example by resolving from
  // /etc/hosts).
  if (network_rv != net::ERR_IO_PENDING) {
    stale_timer_.Stop();
    RecordSynchronousRequest();
  }
  return network_rv;
}

const base::Optional<net::AddressList>&
StaleHostResolver::RequestImpl::GetAddressResults() const {
  if (network_request_)
    return network_request_->GetAddressResults();

  DCHECK(cache_request_);
  return cache_request_->GetAddressResults();
}

const base::Optional<std::vector<std::string>>&
StaleHostResolver::RequestImpl::GetTextResults() const {
  if (network_request_)
    return network_request_->GetTextResults();

  DCHECK(cache_request_);
  return cache_request_->GetTextResults();
}

const base::Optional<std::vector<net::HostPortPair>>&
StaleHostResolver::RequestImpl::GetHostnameResults() const {
  if (network_request_)
    return network_request_->GetHostnameResults();

  DCHECK(cache_request_);
  return cache_request_->GetHostnameResults();
}

const base::Optional<net::HostCache::EntryStaleness>&
StaleHostResolver::RequestImpl::GetStaleInfo() const {
  if (network_request_)
    return network_request_->GetStaleInfo();

  DCHECK(cache_request_);
  return cache_request_->GetStaleInfo();
}

void StaleHostResolver::RequestImpl::ChangeRequestPriority(
    net::RequestPriority priority) {
  if (network_request_) {
    network_request_->ChangeRequestPriority(priority);
  } else {
    DCHECK(cache_request_);
    cache_request_->ChangeRequestPriority(priority);
  }
}

void StaleHostResolver::RequestImpl::OnNetworkRequestComplete(int error) {
  DCHECK(resolver_);
  DCHECK(have_network_request());
  DCHECK(!have_returned());

  bool return_stale_data_instead_of_network_name_not_resolved =
      resolver_->options_.use_stale_on_name_not_resolved &&
      error == net::ERR_NAME_NOT_RESOLVED && have_cache_data();

  RecordNetworkRequest(error,
                       return_stale_data_instead_of_network_name_not_resolved);

  stale_timer_.Stop();

  if (return_stale_data_instead_of_network_name_not_resolved) {
    network_request_.reset();
    std::move(result_callback_).Run(cache_error_);
  } else {
    cache_request_.reset();
    std::move(result_callback_).Run(error);
  }
}

bool StaleHostResolver::RequestImpl::CacheDataIsUsable() const {
  DCHECK(resolver_);
  DCHECK(cache_request_);

  if (cache_error_ != net::OK)
    return false;

  DCHECK(cache_request_->GetStaleInfo());
  const net::HostCache::EntryStaleness& staleness =
      cache_request_->GetStaleInfo().value();

  if (resolver_->options_.max_expired_time != base::TimeDelta() &&
      staleness.expired_by > resolver_->options_.max_expired_time) {
    return false;
  }
  if (resolver_->options_.max_stale_uses > 0 &&
      staleness.stale_hits > resolver_->options_.max_stale_uses) {
    return false;
  }
  if (!resolver_->options_.allow_other_network &&
      staleness.network_changes > 0) {
    return false;
  }
  return true;
}

void StaleHostResolver::RequestImpl::OnStaleDelayElapsed() {
  DCHECK(!have_returned());
  DCHECK(have_cache_data());
  DCHECK(have_network_request());

  // If resolver is destroyed after starting a request, the request is
  // considered cancelled and callbacks must not be invoked. Logging the
  // cancellation will happen on destruction of |this|.
  if (!resolver_) {
    network_request_.reset();
    return;
  }
  DCHECK(CacheDataIsUsable());

  // Detach |network_request_| to allow it to complete and backfill the cache
  // even if |this| is destroyed.
  resolver_->DetachRequest(std::move(network_request_));

  RecordLateRequest();
  std::move(result_callback_).Run(cache_error_);
}

void StaleHostResolver::RequestImpl::RecordSynchronousRequest() {
  RecordRequestOutcome(SYNCHRONOUS);
}

void StaleHostResolver::RequestImpl::RecordNetworkRequest(
    int error,
    bool returned_stale_data_instead_of_network_name_not_resolved) {
  DCHECK(resolver_);

  if (have_cache_data()) {
    RecordTimeDelta(resolver_->tick_clock_->NowTicks(),
                    stale_timer_.desired_run_time());

    if (cache_request_->GetAddressResults() && error == net::OK &&
        network_request_->GetAddressResults()) {
      RecordAddressListDelta(FindAddressListDeltaType(
          cache_request_->GetAddressResults().value(),
          network_request_->GetAddressResults().value()));
    }

    if (returned_stale_data_instead_of_network_name_not_resolved) {
      RecordRequestOutcome(STALE_INSTEAD_OF_NETWORK_NAME_NOT_RESOLVED);
    } else {
      RecordRequestOutcome(NETWORK_WITH_STALE);
      RecordCacheSizes(restore_size_, current_size_);
    }
  } else {
    RecordRequestOutcome(NETWORK_WITHOUT_STALE);
  }
}

void StaleHostResolver::RequestImpl::RecordLateRequest() {
  DCHECK(resolver_);
  DCHECK(have_cache_data());

  RecordTimeDelta(resolver_->tick_clock_->NowTicks(),
                  stale_timer_.desired_run_time());
  RecordRequestOutcome(STALE_BEFORE_NETWORK);
}

void StaleHostResolver::RequestImpl::RecordCanceledRequest() {
  DCHECK(!have_returned());

  if (have_cache_data())
    RecordRequestOutcome(CANCELED_WITH_STALE);
  else
    RecordRequestOutcome(CANCELED_WITHOUT_STALE);
}

StaleHostResolver::StaleOptions::StaleOptions()
    : allow_other_network(false),
      max_stale_uses(0),
      use_stale_on_name_not_resolved(false) {}

StaleHostResolver::StaleHostResolver(
    std::unique_ptr<net::ContextHostResolver> inner_resolver,
    const StaleOptions& stale_options)
    : inner_resolver_(std::move(inner_resolver)),
      options_(stale_options),
      weak_ptr_factory_(this) {
  DCHECK_LE(0, stale_options.max_expired_time.InMicroseconds());
  DCHECK_LE(0, stale_options.max_stale_uses);
}

StaleHostResolver::~StaleHostResolver() {}

std::unique_ptr<net::HostResolver::ResolveHostRequest>
StaleHostResolver::CreateRequest(
    const net::HostPortPair& host,
    const net::NetLogWithSource& net_log,
    const base::Optional<ResolveHostParameters>& optional_parameters) {
  DCHECK(tick_clock_);
  return std::make_unique<RequestImpl>(
      weak_ptr_factory_.GetWeakPtr(), host, net_log,
      optional_parameters.value_or(ResolveHostParameters()), tick_clock_);
}

bool StaleHostResolver::HasCached(base::StringPiece hostname,
                                  net::HostCache::Entry::Source* source_out,
                                  net::HostCache::EntryStaleness* stale_out,
                                  bool* secure_out) const {
  return inner_resolver_->HasCached(hostname, source_out, stale_out,
                                    secure_out);
}

void StaleHostResolver::SetDnsClientEnabled(bool enabled) {
  inner_resolver_->SetDnsClientEnabled(enabled);
}

net::HostCache* StaleHostResolver::GetHostCache() {
  return inner_resolver_->GetHostCache();
}

std::unique_ptr<base::Value> StaleHostResolver::GetDnsConfigAsValue() const {
  return inner_resolver_->GetDnsConfigAsValue();
}

void StaleHostResolver::OnNetworkRequestComplete(
    ResolveHostRequest* network_request,
    base::WeakPtr<RequestImpl> stale_request,
    int error) {
  if (detached_requests_.erase(network_request))
    return;

  // If not a detached request, there should still be an owning RequestImpl.
  // Otherwise the request should have been cancelled and this method never
  // called.
  DCHECK(stale_request);

  stale_request->OnNetworkRequestComplete(error);
}

void StaleHostResolver::DetachRequest(
    std::unique_ptr<ResolveHostRequest> request) {
  DCHECK_EQ(0u, detached_requests_.count(request.get()));
  detached_requests_[request.get()] = std::move(request);
}

void StaleHostResolver::SetTickClockForTesting(
    const base::TickClock* tick_clock) {
  tick_clock_ = tick_clock;
  inner_resolver_->SetTickClockForTesting(tick_clock);
}

}  // namespace cronet
