blob: 3a775edaace43289b3d1a7a4c7c96b2c337b0f7e [file] [log] [blame]
// 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.
#ifndef NET_DNS_DNS_SERVER_ITERATOR_H_
#define NET_DNS_DNS_SERVER_ITERATOR_H_
#include <stddef.h>
#include <vector>
#include "net/base/net_export.h"
#include "net/dns/public/secure_dns_mode.h"
namespace net {
class DnsSession;
class ResolveContext;
// Iterator used to get the next server to try for a DNS transaction.
// Each iterator should be scoped to a single query. A new query, therefore,
// requires a new iterator.
//
// Finds the first eligible server below the global failure limits
// (|max_failures|), or if no eligible servers are below failure limits, the
// eligible one with the oldest last failure. Global failures are tracked by
// ResolveContext.
//
// If |session| goes out of date, this iterator will report that no attempts are
// available and thus cease to return anything.
class NET_EXPORT_PRIVATE DnsServerIterator {
public:
DnsServerIterator(size_t nameservers_size,
size_t starting_index,
int max_times_returned,
int max_failures,
const ResolveContext* resolve_context,
const DnsSession* session);
virtual ~DnsServerIterator();
// Not copy or moveable.
DnsServerIterator(const DnsServerIterator&) = delete;
DnsServerIterator& operator=(const DnsServerIterator&) = delete;
DnsServerIterator(DnsServerIterator&&) = delete;
// Return the index of the next server to be attempted.
// Should only be called if AttemptAvailable() is true.
virtual size_t GetNextAttemptIndex() = 0;
virtual bool AttemptAvailable() = 0;
protected:
// The number of times each server index was returned.
std::vector<int> times_returned_;
// The number of attempts that will be made per server.
int max_times_returned_;
// The failure limit before a server is skipped in the attempt ordering.
// Servers past their failure limit will only be used once all remaining
// servers are also past their failure limit.
int max_failures_;
const ResolveContext* resolve_context_;
// The first server index to try when GetNextAttemptIndex() is called.
size_t next_index_;
const DnsSession* session_;
};
// Iterator used to get the next server to try for a DoH transaction.
// Each iterator should be scoped to a single query. A new query, therefore,
// requires a new iterator.
//
// Finds the first eligible server below the global failure limits
// (|max_failures|), or if no eligible servers are below failure limits, the
// eligible one with the oldest last failure. Global failures are tracked by
// ResolveContext.
//
// Once a server is returned |max_times_returned| times, it is ignored.
//
// If in AUTOMATIC mode, DoH servers are only eligible if "available". See
// GetDohServerAvailability() for details.
class NET_EXPORT_PRIVATE DohDnsServerIterator : public DnsServerIterator {
public:
DohDnsServerIterator(size_t nameservers_size,
size_t starting_index,
int max_times_returned,
int max_failures,
const SecureDnsMode& secure_dns_mode,
const ResolveContext* resolve_context,
const DnsSession* session)
: DnsServerIterator(nameservers_size,
starting_index,
max_times_returned,
max_failures,
resolve_context,
session),
secure_dns_mode_(secure_dns_mode) {}
~DohDnsServerIterator() override = default;
// Not copy or moveable.
DohDnsServerIterator(const DohDnsServerIterator&) = delete;
DohDnsServerIterator& operator=(const DohDnsServerIterator&) = delete;
DohDnsServerIterator(DohDnsServerIterator&&) = delete;
size_t GetNextAttemptIndex() override;
// Return true if any servers in the list still has attempts available.
// False otherwise. An attempt is possible if any server, that is available,
// is under max_times_returned_ tries.
bool AttemptAvailable() override;
private:
SecureDnsMode secure_dns_mode_;
};
// Iterator used to get the next server to try for a classic DNS transaction.
// Each iterator should be scoped to a single query. A new query, therefore,
// requires a new iterator.
//
// Finds the first eligible server below the global failure limits
// (|max_failures|), or if no eligible servers are below failure limits, the
// eligible one with the oldest last failure. Global failures are tracked by
// ResolveContext.
// Once a server is returned |max_times_returned| times, it is ignored.
class NET_EXPORT_PRIVATE ClassicDnsServerIterator : public DnsServerIterator {
public:
ClassicDnsServerIterator(size_t nameservers_size,
size_t starting_index,
int max_times_returned,
int max_failures,
const ResolveContext* resolve_context,
const DnsSession* session)
: DnsServerIterator(nameservers_size,
starting_index,
max_times_returned,
max_failures,
resolve_context,
session) {}
~ClassicDnsServerIterator() override = default;
// Not copy or moveable.
ClassicDnsServerIterator(const ClassicDnsServerIterator&) = delete;
ClassicDnsServerIterator& operator=(const ClassicDnsServerIterator&) = delete;
ClassicDnsServerIterator(ClassicDnsServerIterator&&) = delete;
size_t GetNextAttemptIndex() override;
// Return true if any servers in the list still has attempts available.
// False otherwise. An attempt is possible if any server is under
// max_times_returned_ tries.
bool AttemptAvailable() override;
};
} // namespace net
#endif // NET_DNS_DNS_SERVER_ITERATOR_H_