xref: /aosp_15_r20/external/cronet/net/dns/public/doh_provider_entry.cc (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 #include "net/dns/public/doh_provider_entry.h"
6 
7 #include <string_view>
8 #include <utility>
9 
10 #include "base/check_op.h"
11 #include "base/feature_list.h"
12 #include "base/no_destructor.h"
13 #include "base/ranges/algorithm.h"
14 #include "net/dns/public/dns_over_https_server_config.h"
15 #include "net/dns/public/util.h"
16 
17 namespace net {
18 
19 namespace {
20 
ParseIPs(const std::set<std::string_view> & ip_strs)21 std::set<IPAddress> ParseIPs(const std::set<std::string_view>& ip_strs) {
22   std::set<IPAddress> ip_addresses;
23   for (std::string_view ip_str : ip_strs) {
24     IPAddress ip_address;
25     bool success = ip_address.AssignFromIPLiteral(ip_str);
26     DCHECK(success);
27     ip_addresses.insert(std::move(ip_address));
28   }
29   return ip_addresses;
30 }
31 
ParseValidDohTemplate(std::string server_template,const std::set<std::string_view> & endpoint_ip_strs)32 DnsOverHttpsServerConfig ParseValidDohTemplate(
33     std::string server_template,
34     const std::set<std::string_view>& endpoint_ip_strs) {
35   std::set<IPAddress> endpoint_ips = ParseIPs(endpoint_ip_strs);
36 
37   std::vector<std::vector<IPAddress>> endpoints;
38 
39   // Note: `DnsOverHttpsServerConfig` supports separate groups of endpoint IPs,
40   // but for now we'll just support all endpoint IPs combined into one grouping
41   // since the only use of the endpoint IPs in the server config combines them
42   // anyway.
43   if (!endpoint_ips.empty()) {
44     endpoints.emplace_back(endpoint_ips.begin(), endpoint_ips.end());
45   }
46 
47   auto parsed_template = DnsOverHttpsServerConfig::FromString(
48       std::move(server_template), endpoints);
49   DCHECK(parsed_template.has_value());  // Template must be valid.
50   return std::move(*parsed_template);
51 }
52 
53 }  // namespace
54 
55 #define MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(feature_name, feature_state) \
56   ([]() {                                                                  \
57     static BASE_FEATURE(k##feature_name, #feature_name, feature_state);    \
58     return &k##feature_name;                                               \
59   })()
60 
61 // static
GetList()62 const DohProviderEntry::List& DohProviderEntry::GetList() {
63   // See /net/docs/adding_doh_providers.md for instructions on modifying this
64   // DoH provider list.
65   //
66   // The provider names in these entries should be kept in sync with the
67   // DohProviderId histogram suffix list in
68   // tools/metrics/histograms/metadata/histogram_suffixes_list.xml.
69   static const base::NoDestructor<DohProviderEntry::List> providers{{
70       new DohProviderEntry(
71           "AlekBergNl",
72           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
73               DohProviderAlekBergNl, base::FEATURE_ENABLED_BY_DEFAULT),
74           /*dns_over_53_server_ip_strs=*/{}, /*dns_over_tls_hostnames=*/{},
75           "https://dnsnl.alekberg.net/dns-query{?dns}",
76           /*ui_name=*/"alekberg.net (NL)",
77           /*privacy_policy=*/"https://alekberg.net/privacy",
78           /*display_globally=*/false,
79           /*display_countries=*/{"NL"}, LoggingLevel::kNormal),
80       new DohProviderEntry(
81           "CleanBrowsingAdult",
82           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
83               DohProviderCleanBrowsingAdult, base::FEATURE_ENABLED_BY_DEFAULT),
84           {"185.228.168.10", "185.228.169.11", "2a0d:2a00:1::1",
85            "2a0d:2a00:2::1"},
86           /*dns_over_tls_hostnames=*/{"adult-filter-dns.cleanbrowsing.org"},
87           "https://doh.cleanbrowsing.org/doh/adult-filter{?dns}",
88           /*ui_name=*/"", /*privacy_policy=*/"",
89           /*display_globally=*/false, /*display_countries=*/{},
90           LoggingLevel::kNormal),
91       new DohProviderEntry(
92           "CleanBrowsingFamily",
93           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
94               DohProviderCleanBrowsingFamily, base::FEATURE_ENABLED_BY_DEFAULT),
95           {"185.228.168.168", "185.228.169.168",
96            "2a0d:2a00:1::", "2a0d:2a00:2::"},
97           /*dns_over_tls_hostnames=*/{"family-filter-dns.cleanbrowsing.org"},
98           "https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
99           /*ui_name=*/"CleanBrowsing (Family Filter)",
100           /*privacy_policy=*/"https://cleanbrowsing.org/privacy",
101           /*display_globally=*/true, /*display_countries=*/{},
102           LoggingLevel::kNormal),
103       new DohProviderEntry(
104           "CleanBrowsingSecure",
105           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
106               DohProviderCleanBrowsingSecure, base::FEATURE_ENABLED_BY_DEFAULT),
107           {"185.228.168.9", "185.228.169.9", "2a0d:2a00:1::2",
108            "2a0d:2a00:2::2"},
109           /*dns_over_tls_hostnames=*/{"security-filter-dns.cleanbrowsing.org"},
110           "https://doh.cleanbrowsing.org/doh/security-filter{?dns}",
111           /*ui_name=*/"", /*privacy_policy=*/"", /*display_globally=*/false,
112           /*display_countries=*/{}, LoggingLevel::kNormal),
113       new DohProviderEntry(
114           "Cloudflare",
115           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
116               DohProviderCloudflare, base::FEATURE_ENABLED_BY_DEFAULT),
117           {"1.1.1.1", "1.0.0.1", "2606:4700:4700::1111",
118            "2606:4700:4700::1001"},
119           /*dns_over_tls_hostnames=*/
120           {"one.one.one.one", "1dot1dot1dot1.cloudflare-dns.com"},
121           "https://chrome.cloudflare-dns.com/dns-query",
122           /*ui_name=*/"Cloudflare (1.1.1.1)",
123           "https://developers.cloudflare.com/1.1.1.1/privacy/"
124           /*privacy_policy=*/"public-dns-resolver/",
125           /*display_globally=*/true, /*display_countries=*/{},
126           LoggingLevel::kExtra),
127       new DohProviderEntry(
128           "Comcast",
129           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
130               DohProviderComcast, base::FEATURE_ENABLED_BY_DEFAULT),
131           {"75.75.75.75", "75.75.76.76", "2001:558:feed::1",
132            "2001:558:feed::2"},
133           /*dns_over_tls_hostnames=*/{"dot.xfinity.com"},
134           "https://doh.xfinity.com/dns-query{?dns}", /*ui_name=*/"",
135           /*privacy_policy*/ "", /*display_globally=*/false,
136           /*display_countries=*/{}, LoggingLevel::kExtra),
137       new DohProviderEntry(
138           "Cox",
139           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
140               DohProviderCox, base::FEATURE_ENABLED_BY_DEFAULT),
141           {"68.105.28.11", "68.105.28.12", "2001:578:3f::30"},
142           /*dns_over_tls_hostnames=*/{"dot.cox.net"},
143           "https://doh.cox.net/dns-query",
144           /*ui_name=*/"", /*privacy_policy=*/"",
145           /*display_globally=*/false, /*display_countries=*/{},
146           LoggingLevel::kNormal),
147       new DohProviderEntry(
148           "Cznic",
149           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
150               DohProviderCznic, base::FEATURE_ENABLED_BY_DEFAULT),
151           {"185.43.135.1", "193.17.47.1", "2001:148f:fffe::1",
152            "2001:148f:ffff::1"},
153           /*dns_over_tls_hostnames=*/{"odvr.nic.cz"}, "https://odvr.nic.cz/doh",
154           /*ui_name=*/"CZ.NIC ODVR",
155           /*privacy_policy=*/"https://www.nic.cz/odvr/",
156           /*display_globally=*/false, /*display_countries=*/{"CZ"},
157           LoggingLevel::kNormal),
158       new DohProviderEntry(
159           "Dnssb",
160           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
161               DohProviderDnssb, base::FEATURE_ENABLED_BY_DEFAULT),
162           {"185.222.222.222", "45.11.45.11", "2a09::", "2a11::"},
163           /*dns_over_tls_hostnames=*/{"dns.sb"},
164           "https://doh.dns.sb/dns-query{?dns}", /*ui_name=*/"DNS.SB",
165           /*privacy_policy=*/"https://dns.sb/privacy/",
166           /*display_globally=*/false, /*display_countries=*/{"EE", "DE"},
167           LoggingLevel::kNormal),
168       new DohProviderEntry(
169           "Google",
170           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
171               DohProviderGoogle, base::FEATURE_ENABLED_BY_DEFAULT),
172           {"8.8.8.8", "8.8.4.4", "2001:4860:4860::8888",
173            "2001:4860:4860::8844"},
174           /*dns_over_tls_hostnames=*/
175           {"dns.google", "dns.google.com", "8888.google"},
176           "https://dns.google/dns-query{?dns}",
177           /*ui_name=*/"Google (Public DNS)",
178           "https://developers.google.com/speed/public-dns/"
179           /*privacy_policy=*/"privacy",
180           /*display_globally=*/true, /*display_countries=*/{},
181           LoggingLevel::kExtra),
182       new DohProviderEntry(
183           "GoogleDns64",
184           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
185               DohProviderGoogleDns64, base::FEATURE_ENABLED_BY_DEFAULT),
186           {"2001:4860:4860::64", "2001:4860:4860::6464"},
187           /*dns_over_tls_hostnames=*/{"dns64.dns.google"},
188           "https://dns64.dns.google/dns-query{?dns}",
189           /*ui_name=*/"", /*privacy_policy=*/"",
190           /*display_globally=*/false,
191           /*display_countries=*/{}, LoggingLevel::kNormal),
192       new DohProviderEntry(
193           "Iij",
194           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
195               DohProviderIij, base::FEATURE_ENABLED_BY_DEFAULT),
196           /*dns_over_53_server_ip_strs=*/{},
197           /*dns_over_tls_hostnames=*/{}, "https://public.dns.iij.jp/dns-query",
198           /*ui_name=*/"IIJ (Public DNS)",
199           /*privacy_policy=*/"https://public.dns.iij.jp/",
200           /*display_globally=*/false, /*display_countries=*/{"JP"},
201           LoggingLevel::kNormal),
202       new DohProviderEntry(
203           "Levonet",
204           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
205               DohProviderLevonet, base::FEATURE_ENABLED_BY_DEFAULT),
206           {"109.236.119.2", "109.236.120.2", "2a02:6ca3:0:1::2",
207            "2a02:6ca3:0:2::2"},
208           /*dns_over_tls_hostnames=*/{},
209           "https://dns.levonet.sk/dns-query{?dns}",
210           /*ui_name=*/"", /*privacy_policy=*/"", /*display_globally=*/false,
211           /*display_countries=*/{}, LoggingLevel::kNormal,
212           {"109.236.119.2", "109.236.120.2", "2a02:6ca3:0:1::2",
213            "2a02:6ca3:0:2::2"}),
214       new DohProviderEntry(
215           "NextDns",
216           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
217               DohProviderNextDns, base::FEATURE_ENABLED_BY_DEFAULT),
218           /*dns_over_53_server_ip_strs=*/{},
219           /*dns_over_tls_hostnames=*/{}, "https://chromium.dns.nextdns.io",
220           /*ui_name=*/"NextDNS",
221           /*privacy_policy=*/"https://nextdns.io/privacy",
222           /*display_globally=*/false, /*display_countries=*/{"US"},
223           LoggingLevel::kNormal),
224       new DohProviderEntry(
225           "OpenDNS",
226           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
227               DohProviderOpenDNS, base::FEATURE_ENABLED_BY_DEFAULT),
228           {"208.67.222.222", "208.67.220.220", "2620:119:35::35",
229            "2620:119:53::53"},
230           /*dns_over_tls_hostnames=*/{},
231           "https://doh.opendns.com/dns-query{?dns}", /*ui_name=*/"OpenDNS",
232           "https://www.cisco.com/c/en/us/about/legal/"
233           /*privacy_policy=*/"privacy-full.html",
234           /*display_globally=*/true, /*display_countries=*/{},
235           LoggingLevel::kNormal),
236       new DohProviderEntry(
237           "OpenDNSFamily",
238           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
239               DohProviderOpenDNSFamily, base::FEATURE_ENABLED_BY_DEFAULT),
240           {"208.67.222.123", "208.67.220.123", "2620:119:35::123",
241            "2620:119:53::123"},
242           /*dns_over_tls_hostnames=*/{},
243           "https://doh.familyshield.opendns.com/dns-query{?dns}",
244           /*ui_name=*/"", /*privacy_policy=*/"", /*display_globally=*/false,
245           /*display_countries=*/{}, LoggingLevel::kNormal),
246       new DohProviderEntry(
247           "Quad9Cdn",
248           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
249               DohProviderQuad9Cdn, base::FEATURE_ENABLED_BY_DEFAULT),
250           {"9.9.9.11", "149.112.112.11", "2620:fe::11", "2620:fe::fe:11"},
251           /*dns_over_tls_hostnames=*/{"dns11.quad9.net"},
252           "https://dns11.quad9.net/dns-query", /*ui_name=*/"",
253           /*privacy_policy=*/"", /*display_globally=*/false,
254           /*display_countries=*/{}, LoggingLevel::kNormal),
255       new DohProviderEntry(
256           "Quad9Insecure",
257           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
258               DohProviderQuad9Insecure, base::FEATURE_ENABLED_BY_DEFAULT),
259           {"9.9.9.10", "149.112.112.10", "2620:fe::10", "2620:fe::fe:10"},
260           /*dns_over_tls_hostnames=*/{"dns10.quad9.net"},
261           "https://dns10.quad9.net/dns-query", /*ui_name=*/"",
262           /*privacy_policy=*/"", /*display_globally=*/false,
263           /*display_countries=*/{}, LoggingLevel::kNormal),
264       new DohProviderEntry(
265           "Quad9Secure",
266           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
267               DohProviderQuad9Secure, base::FEATURE_DISABLED_BY_DEFAULT),
268           {"9.9.9.9", "149.112.112.112", "2620:fe::fe", "2620:fe::9"},
269           /*dns_over_tls_hostnames=*/{"dns.quad9.net", "dns9.quad9.net"},
270           "https://dns.quad9.net/dns-query", /*ui_name=*/"Quad9 (9.9.9.9)",
271           /*privacy_policy=*/"https://www.quad9.net/home/privacy/",
272           /*display_globally=*/true, /*display_countries=*/{},
273           LoggingLevel::kExtra),
274       new DohProviderEntry(
275           "Quickline",
276           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
277               DohProviderQuickline, base::FEATURE_ENABLED_BY_DEFAULT),
278           {"212.60.61.246", "212.60.63.246", "2001:1a88:10:ffff::1",
279            "2001:1a88:10:ffff::2"},
280           /*dns_over_tls_hostnames=*/{"dot.quickline.ch"},
281           "https://doh.quickline.ch/dns-query{?dns}",
282           /*ui_name=*/"", /*privacy_policy=*/"",
283           /*display_globally=*/false,
284           /*display_countries=*/{}, LoggingLevel::kNormal),
285       new DohProviderEntry(
286           "Spectrum1",
287           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
288               DohProviderSpectrum1, base::FEATURE_ENABLED_BY_DEFAULT),
289           {"209.18.47.61", "209.18.47.62", "2001:1998:0f00:0001::1",
290            "2001:1998:0f00:0002::1"},
291           /*dns_over_tls_hostnames=*/{},
292           "https://doh-01.spectrum.com/dns-query{?dns}",
293           /*ui_name=*/"", /*privacy_policy=*/"",
294           /*display_globally=*/false,
295           /*display_countries=*/{}, LoggingLevel::kNormal),
296       new DohProviderEntry(
297           "Spectrum2",
298           MAKE_BASE_FEATURE_WITH_STATIC_STORAGE(
299               DohProviderSpectrum2, base::FEATURE_ENABLED_BY_DEFAULT),
300           {"209.18.47.61", "209.18.47.62", "2001:1998:0f00:0001::1",
301            "2001:1998:0f00:0002::1"},
302           /*dns_over_tls_hostnames=*/{},
303           "https://doh-02.spectrum.com/dns-query{?dns}",
304           /*ui_name=*/"", /*privacy_policy=*/"",
305           /*display_globally=*/false,
306           /*display_countries=*/{}, LoggingLevel::kNormal),
307   }};
308   return *providers;
309 }
310 
311 #undef MAKE_BASE_FEATURE_WITH_STATIC_STORAGE
312 
313 // static
ConstructForTesting(std::string provider,const base::Feature * feature,std::set<std::string_view> dns_over_53_server_ip_strs,std::set<std::string> dns_over_tls_hostnames,std::string dns_over_https_template,std::string ui_name,std::string privacy_policy,bool display_globally,std::set<std::string> display_countries,LoggingLevel logging_level)314 DohProviderEntry DohProviderEntry::ConstructForTesting(
315     std::string provider,
316     const base::Feature* feature,
317     std::set<std::string_view> dns_over_53_server_ip_strs,
318     std::set<std::string> dns_over_tls_hostnames,
319     std::string dns_over_https_template,
320     std::string ui_name,
321     std::string privacy_policy,
322     bool display_globally,
323     std::set<std::string> display_countries,
324     LoggingLevel logging_level) {
325   return DohProviderEntry(
326       std::move(provider), feature, std::move(dns_over_53_server_ip_strs),
327       std::move(dns_over_tls_hostnames), std::move(dns_over_https_template),
328       std::move(ui_name), std::move(privacy_policy), display_globally,
329       std::move(display_countries), logging_level);
330 }
331 
332 DohProviderEntry::~DohProviderEntry() = default;
333 
DohProviderEntry(std::string provider,const base::Feature * feature,std::set<std::string_view> dns_over_53_server_ip_strs,std::set<std::string> dns_over_tls_hostnames,std::string dns_over_https_template,std::string ui_name,std::string privacy_policy,bool display_globally,std::set<std::string> display_countries,LoggingLevel logging_level,std::set<std::string_view> dns_over_https_server_ip_strs)334 DohProviderEntry::DohProviderEntry(
335     std::string provider,
336     const base::Feature* feature,
337     std::set<std::string_view> dns_over_53_server_ip_strs,
338     std::set<std::string> dns_over_tls_hostnames,
339     std::string dns_over_https_template,
340     std::string ui_name,
341     std::string privacy_policy,
342     bool display_globally,
343     std::set<std::string> display_countries,
344     LoggingLevel logging_level,
345     std::set<std::string_view> dns_over_https_server_ip_strs)
346     : provider(std::move(provider)),
347       feature(*feature),
348       ip_addresses(ParseIPs(dns_over_53_server_ip_strs)),
349       dns_over_tls_hostnames(std::move(dns_over_tls_hostnames)),
350       doh_server_config(
351           ParseValidDohTemplate(std::move(dns_over_https_template),
352                                 std::move(dns_over_https_server_ip_strs))),
353       ui_name(std::move(ui_name)),
354       privacy_policy(std::move(privacy_policy)),
355       display_globally(display_globally),
356       display_countries(std::move(display_countries)),
357       logging_level(logging_level) {
358   DCHECK(!display_globally || this->display_countries.empty());
359   if (display_globally || !this->display_countries.empty()) {
360     DCHECK(!this->ui_name.empty());
361     DCHECK(!this->privacy_policy.empty());
362   }
363   for (const auto& display_country : this->display_countries) {
364     DCHECK_EQ(2u, display_country.size());
365   }
366 }
367 
368 }  // namespace net
369