// Copyright 2020 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 "net/dns/dns_server_iterator.h"

#include "base/optional.h"
#include "base/time/time.h"
#include "net/dns/dns_session.h"
#include "net/dns/resolve_context.h"

namespace net {
DnsServerIterator::DnsServerIterator(size_t nameservers_size,
                                     size_t starting_index,
                                     int max_times_returned,
                                     int max_failures,
                                     const ResolveContext* resolve_context,
                                     const DnsSession* session)
    : times_returned_(nameservers_size, 0),
      max_times_returned_(max_times_returned),
      max_failures_(max_failures),
      resolve_context_(resolve_context),
      next_index_(starting_index),
      session_(session) {}

DnsServerIterator::~DnsServerIterator() = default;

size_t DohDnsServerIterator::GetNextAttemptIndex() {
  DCHECK(resolve_context_->IsCurrentSession(session_));
  DCHECK(AttemptAvailable());

  // Because AttemptAvailable() should always be true before running this
  // function we can assume that an attemptable DoH server exists.

  // Check if the next index is available and hasn't hit its failure limit. If
  // not, try the next one and so on until we've tried them all.
  base::Optional<size_t> least_recently_failed_index;
  base::TimeTicks least_recently_failed_time;

  size_t previous_index = next_index_;
  size_t curr_index;

  do {
    curr_index = next_index_;
    next_index_ = (next_index_ + 1) % times_returned_.size();

    // If the DoH mode is "secure" then don't check GetDohServerAvailability()
    // because we try every server regardless of availability.
    bool secure_or_available_server =
        secure_dns_mode_ == SecureDnsMode::kSecure ||
        resolve_context_->GetDohServerAvailability(curr_index, session_);

    // If we've tried this server |max_times_returned_| already, then we're done
    // with it. Similarly skip this server if it isn't available and we're not
    // in secure mode.
    if (times_returned_[curr_index] >= max_times_returned_ ||
        !secure_or_available_server)
      continue;

    if (resolve_context_->doh_server_stats_[curr_index].last_failure_count <
        max_failures_) {
      times_returned_[curr_index]++;
      return curr_index;
    }

    // Update the least recently failed server if needed.
    base::TimeTicks curr_index_failure_time =
        resolve_context_->doh_server_stats_[curr_index].last_failure;
    if (!least_recently_failed_index ||
        curr_index_failure_time < least_recently_failed_time) {
      least_recently_failed_time = curr_index_failure_time;
      least_recently_failed_index = curr_index;
    }
  } while (next_index_ != previous_index);

  // At this point the only available servers we haven't attempted
  // |max_times_returned_| times are at their failure limit. Return the server
  // with the least recent failure.

  DCHECK(least_recently_failed_index.has_value());
  times_returned_[least_recently_failed_index.value()]++;
  return least_recently_failed_index.value();
}

bool DohDnsServerIterator::AttemptAvailable() {
  if (!resolve_context_->IsCurrentSession(session_))
    return false;

  for (size_t i = 0; i < times_returned_.size(); i++) {
    // If the DoH mode is "secure" then don't check GetDohServerAvailability()
    // because we try every server regardless of availability.
    bool secure_or_available_server =
        secure_dns_mode_ == SecureDnsMode::kSecure ||
        resolve_context_->GetDohServerAvailability(i, session_);

    if (times_returned_[i] < max_times_returned_ && secure_or_available_server)
      return true;
  }
  return false;
}

size_t ClassicDnsServerIterator::GetNextAttemptIndex() {
  DCHECK(resolve_context_->IsCurrentSession(session_));
  DCHECK(AttemptAvailable());

  // Because AttemptAvailable() should always be true before running this
  // function we can assume that an attemptable DNS server exists.

  // Check if the next index is available and hasn't hit its failure limit. If
  // not, try the next one and so on until we've tried them all.
  base::Optional<size_t> least_recently_failed_index;
  base::TimeTicks least_recently_failed_time;

  size_t previous_index = next_index_;
  size_t curr_index;

  do {
    curr_index = next_index_;
    next_index_ = (next_index_ + 1) % times_returned_.size();

    // If we've tried this server |max_times_returned_| already, then we're done
    // with it.
    if (times_returned_[curr_index] >= max_times_returned_)
      continue;

    if (resolve_context_->classic_server_stats_[curr_index].last_failure_count <
        max_failures_) {
      times_returned_[curr_index]++;
      return curr_index;
    }

    // Update the least recently failed server if needed.
    base::TimeTicks curr_index_failure_time =
        resolve_context_->classic_server_stats_[curr_index].last_failure;
    if (!least_recently_failed_index ||
        curr_index_failure_time < least_recently_failed_time) {
      least_recently_failed_time = curr_index_failure_time;
      least_recently_failed_index = curr_index;
    }
  } while (next_index_ != previous_index);

  // At this point the only servers we haven't attempted |max_times_returned_|
  // times are at their failure limit. Return the server with the least recent
  // failure.

  DCHECK(least_recently_failed_index.has_value());
  times_returned_[least_recently_failed_index.value()]++;
  return least_recently_failed_index.value();
}

bool ClassicDnsServerIterator::AttemptAvailable() {
  if (!resolve_context_->IsCurrentSession(session_))
    return false;

  for (int i : times_returned_) {
    if (i < max_times_returned_)
      return true;
  }
  return false;
}

}  // namespace net
