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