xref: /aosp_15_r20/external/cronet/net/dns/dns_server_iterator.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_DNS_DNS_SERVER_ITERATOR_H_
6 #define NET_DNS_DNS_SERVER_ITERATOR_H_
7 
8 #include <stddef.h>
9 #include <vector>
10 
11 #include "base/memory/raw_ptr.h"
12 #include "net/base/net_export.h"
13 #include "net/dns/public/secure_dns_mode.h"
14 
15 namespace net {
16 
17 class DnsSession;
18 class ResolveContext;
19 
20 // Iterator used to get the next server to try for a DNS transaction.
21 // Each iterator should be scoped to a single query. A new query, therefore,
22 // requires a new iterator.
23 //
24 // Finds the first eligible server below the global failure limits
25 // (|max_failures|), or if no eligible servers are below failure limits, the
26 // eligible one with the oldest last failure. Global failures are tracked by
27 // ResolveContext.
28 //
29 // If |session| goes out of date, this iterator will report that no attempts are
30 // available and thus cease to return anything.
31 class NET_EXPORT_PRIVATE DnsServerIterator {
32  public:
33   DnsServerIterator(size_t nameservers_size,
34                     size_t starting_index,
35                     int max_times_returned,
36                     int max_failures,
37                     const ResolveContext* resolve_context,
38                     const DnsSession* session);
39 
40   virtual ~DnsServerIterator();
41 
42   // Not copy or moveable.
43   DnsServerIterator(const DnsServerIterator&) = delete;
44   DnsServerIterator& operator=(const DnsServerIterator&) = delete;
45   DnsServerIterator(DnsServerIterator&&) = delete;
46 
47   // Return the index of the next server to be attempted.
48   // Should only be called if AttemptAvailable() is true.
49   virtual size_t GetNextAttemptIndex() = 0;
50 
51   virtual bool AttemptAvailable() = 0;
52 
53  protected:
54   // The number of times each server index was returned.
55   std::vector<int> times_returned_;
56   // The number of attempts that will be made per server.
57   int max_times_returned_;
58   // The failure limit before a server is skipped in the attempt ordering.
59   // Servers past their failure limit will only be used once all remaining
60   // servers are also past their failure limit.
61   int max_failures_;
62   raw_ptr<const ResolveContext, DanglingUntriaged> resolve_context_;
63   // The first server index to try when GetNextAttemptIndex() is called.
64   size_t next_index_;
65 
66   raw_ptr<const DnsSession, DanglingUntriaged> session_;
67 };
68 
69 // Iterator used to get the next server to try for a DoH transaction.
70 // Each iterator should be scoped to a single query. A new query, therefore,
71 // requires a new iterator.
72 //
73 // Finds the first eligible server below the global failure limits
74 // (|max_failures|), or if no eligible servers are below failure limits, the
75 // eligible one with the oldest last failure. Global failures are tracked by
76 // ResolveContext.
77 //
78 // Once a server is returned |max_times_returned| times, it is ignored.
79 //
80 // If in AUTOMATIC mode, DoH servers are only eligible if "available".  See
81 // GetDohServerAvailability() for details.
82 class NET_EXPORT_PRIVATE DohDnsServerIterator : public DnsServerIterator {
83  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)84   DohDnsServerIterator(size_t nameservers_size,
85                        size_t starting_index,
86                        int max_times_returned,
87                        int max_failures,
88                        const SecureDnsMode& secure_dns_mode,
89                        const ResolveContext* resolve_context,
90                        const DnsSession* session)
91       : DnsServerIterator(nameservers_size,
92                           starting_index,
93                           max_times_returned,
94                           max_failures,
95                           resolve_context,
96                           session),
97         secure_dns_mode_(secure_dns_mode) {}
98 
99   ~DohDnsServerIterator() override = default;
100 
101   // Not copy or moveable.
102   DohDnsServerIterator(const DohDnsServerIterator&) = delete;
103   DohDnsServerIterator& operator=(const DohDnsServerIterator&) = delete;
104   DohDnsServerIterator(DohDnsServerIterator&&) = delete;
105 
106   size_t GetNextAttemptIndex() override;
107 
108   // Return true if any servers in the list still has attempts available.
109   // False otherwise. An attempt is possible if any server, that is available,
110   // is under max_times_returned_ tries.
111   bool AttemptAvailable() override;
112 
113  private:
114   SecureDnsMode secure_dns_mode_;
115 };
116 
117 // Iterator used to get the next server to try for a classic DNS transaction.
118 // Each iterator should be scoped to a single query. A new query, therefore,
119 // requires a new iterator.
120 //
121 // Finds the first eligible server below the global failure limits
122 // (|max_failures|), or if no eligible servers are below failure limits, the
123 // eligible one with the oldest last failure. Global failures are tracked by
124 // ResolveContext.
125 
126 // Once a server is returned |max_times_returned| times, it is ignored.
127 class NET_EXPORT_PRIVATE ClassicDnsServerIterator : public DnsServerIterator {
128  public:
ClassicDnsServerIterator(size_t nameservers_size,size_t starting_index,int max_times_returned,int max_failures,const ResolveContext * resolve_context,const DnsSession * session)129   ClassicDnsServerIterator(size_t nameservers_size,
130                            size_t starting_index,
131                            int max_times_returned,
132                            int max_failures,
133                            const ResolveContext* resolve_context,
134                            const DnsSession* session)
135       : DnsServerIterator(nameservers_size,
136                           starting_index,
137                           max_times_returned,
138                           max_failures,
139                           resolve_context,
140                           session) {}
141 
142   ~ClassicDnsServerIterator() override = default;
143 
144   // Not copy or moveable.
145   ClassicDnsServerIterator(const ClassicDnsServerIterator&) = delete;
146   ClassicDnsServerIterator& operator=(const ClassicDnsServerIterator&) = delete;
147   ClassicDnsServerIterator(ClassicDnsServerIterator&&) = delete;
148 
149   size_t GetNextAttemptIndex() override;
150 
151   // Return true if any servers in the list still has attempts available.
152   // False otherwise. An attempt is possible if any server is under
153   // max_times_returned_ tries.
154   bool AttemptAvailable() override;
155 };
156 
157 }  // namespace net
158 #endif  // NET_DNS_DNS_SERVER_ITERATOR_H_
159