summaryrefslogtreecommitdiff
path: root/chromium/net/dns/dns_server_iterator.h
blob: b9420b92359f447a3858bc341fa24bd66ff2a0fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// 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 "base/memory/raw_ptr.h"
#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_;
  raw_ptr<const ResolveContext> resolve_context_;
  // The first server index to try when GetNextAttemptIndex() is called.
  size_t next_index_;

  raw_ptr<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_