Separate provider filtering and metrics from UI
This change moves filtering of the DoH provider list and reporting of UMA metrics out of the UI code to dns_util.cc. This simplifies the UI code and enables sharing of functionality with the forthcoming Android DoH control UI. Change-Id: I66d0313d9e913ad1d34ac65a2278771261788b7d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2174779 Commit-Queue: Peter Kasting <pkasting@chromium.org> Reviewed-by: Eric Orth <ericorth@chromium.org> Reviewed-by: Avi Drissman <avi@chromium.org> Reviewed-by: Peter Kasting <pkasting@chromium.org> Cr-Commit-Position: refs/heads/master@{#774500}
This commit is contained in:
@ -2057,6 +2057,7 @@ static_library("browser") {
|
||||
"//components/contextual_search/content:browser",
|
||||
"//components/contextual_search/core:browser",
|
||||
"//components/cookie_config",
|
||||
"//components/country_codes",
|
||||
"//components/crx_file",
|
||||
"//components/data_reduction_proxy/core/browser",
|
||||
"//components/data_use_measurement/core:ascriber",
|
||||
|
@ -77,6 +77,7 @@ include_rules = [
|
||||
"+components/contextual_search/content/common",
|
||||
"+components/contextual_search/core/browser",
|
||||
"+components/cookie_config",
|
||||
"+components/country_codes",
|
||||
"+components/crash/content/app",
|
||||
"+components/crash/content/browser",
|
||||
"+components/crash/core/app",
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/test_navigation_observer.h"
|
||||
#include "net/dns/public/doh_provider_list.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
@ -32,10 +32,9 @@ struct DohParameter {
|
||||
|
||||
std::vector<DohParameter> GetDohServerTestCases() {
|
||||
std::vector<DohParameter> doh_test_cases;
|
||||
const auto& doh_providers = net::GetDohProviderList();
|
||||
for (const auto& doh_provider : doh_providers) {
|
||||
doh_test_cases.emplace_back(doh_provider.provider,
|
||||
doh_provider.dns_over_https_template, true);
|
||||
for (const auto* entry : net::DohProviderEntry::GetList()) {
|
||||
doh_test_cases.emplace_back(entry->provider, entry->dns_over_https_template,
|
||||
true);
|
||||
}
|
||||
// Negative test-case
|
||||
doh_test_cases.emplace_back("NegativeTestExampleCom",
|
||||
|
@ -8,12 +8,15 @@
|
||||
#include <string>
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "base/metrics/histogram_macros.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "chrome/common/chrome_features.h"
|
||||
#include "components/country_codes/country_codes.h"
|
||||
#include "components/embedder_support/pref_names.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "net/dns/dns_config_overrides.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
#include "net/dns/public/util.h"
|
||||
#include "net/third_party/uri_template/uri_template.h"
|
||||
#include "url/gurl.h"
|
||||
@ -26,6 +29,37 @@ namespace {
|
||||
|
||||
const char kAlternateErrorPagesBackup[] = "alternate_error_pages.backup";
|
||||
|
||||
void IncrementDropdownHistogram(net::DohProviderIdForHistogram id,
|
||||
const std::string& doh_template,
|
||||
base::StringPiece old_template,
|
||||
base::StringPiece new_template) {
|
||||
if (doh_template == old_template) {
|
||||
UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Unselected",
|
||||
id);
|
||||
} else if (doh_template == new_template) {
|
||||
UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Selected", id);
|
||||
} else {
|
||||
UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Ignored", id);
|
||||
}
|
||||
}
|
||||
|
||||
bool EntryIsForCountry(const net::DohProviderEntry* entry, int country_id) {
|
||||
if (entry->display_globally) {
|
||||
return true;
|
||||
}
|
||||
const auto& countries = entry->display_countries;
|
||||
bool matches = std::any_of(countries.begin(), countries.end(),
|
||||
[country_id](const std::string& country_code) {
|
||||
return country_codes::CountryStringToCountryID(
|
||||
country_code) == country_id;
|
||||
});
|
||||
if (matches) {
|
||||
DCHECK(!entry->ui_name.empty());
|
||||
DCHECK(!entry->privacy_policy.empty());
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void RegisterProbesSettingBackupPref(PrefRegistrySimple* registry) {
|
||||
@ -68,6 +102,35 @@ void MigrateProbesSettingToOrFromBackup(PrefService* prefs) {
|
||||
}
|
||||
}
|
||||
|
||||
net::DohProviderEntry::List ProvidersForCountry(
|
||||
const net::DohProviderEntry::List& providers,
|
||||
int country_id) {
|
||||
net::DohProviderEntry::List local_providers;
|
||||
std::copy_if(providers.begin(), providers.end(),
|
||||
std::back_inserter(local_providers),
|
||||
[country_id](const auto* entry) {
|
||||
return EntryIsForCountry(entry, country_id);
|
||||
});
|
||||
return local_providers;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetDisabledProviders() {
|
||||
return SplitString(features::kDnsOverHttpsDisabledProvidersParam.Get(), ",",
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
}
|
||||
|
||||
net::DohProviderEntry::List RemoveDisabledProviders(
|
||||
const net::DohProviderEntry::List& providers,
|
||||
const std::vector<string>& disabled_providers) {
|
||||
net::DohProviderEntry::List filtered_providers;
|
||||
std::copy_if(providers.begin(), providers.end(),
|
||||
std::back_inserter(filtered_providers),
|
||||
[&disabled_providers](const auto* entry) {
|
||||
return !base::Contains(disabled_providers, entry->provider);
|
||||
});
|
||||
return filtered_providers;
|
||||
}
|
||||
|
||||
std::vector<base::StringPiece> SplitGroup(base::StringPiece group) {
|
||||
// Templates in a group are whitespace-separated.
|
||||
return SplitStringPiece(group, " ", base::TRIM_WHITESPACE,
|
||||
@ -83,6 +146,28 @@ bool IsValidGroup(base::StringPiece group) {
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateDropdownHistograms(
|
||||
const std::vector<const net::DohProviderEntry*>& providers,
|
||||
base::StringPiece old_template,
|
||||
base::StringPiece new_template) {
|
||||
for (const auto* entry : providers) {
|
||||
IncrementDropdownHistogram(entry->provider_id_for_histogram.value(),
|
||||
entry->dns_over_https_template, old_template,
|
||||
new_template);
|
||||
}
|
||||
// An empty template indicates a custom provider.
|
||||
IncrementDropdownHistogram(net::DohProviderIdForHistogram::kCustom,
|
||||
std::string(), old_template, new_template);
|
||||
}
|
||||
|
||||
void UpdateValidationHistogram(bool valid) {
|
||||
UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ValidationAttemptSuccess", valid);
|
||||
}
|
||||
|
||||
void UpdateProbeHistogram(bool success) {
|
||||
UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ProbeAttemptSuccess", success);
|
||||
}
|
||||
|
||||
void ApplyTemplate(net::DnsConfigOverrides* overrides,
|
||||
base::StringPiece server_template) {
|
||||
std::string server_method;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
|
||||
namespace net {
|
||||
struct DnsConfigOverrides;
|
||||
@ -20,6 +21,22 @@ namespace chrome_browser_net {
|
||||
|
||||
namespace secure_dns {
|
||||
|
||||
// Returns the subset of |providers| that are marked for use in the specified
|
||||
// country.
|
||||
net::DohProviderEntry::List ProvidersForCountry(
|
||||
const net::DohProviderEntry::List& providers,
|
||||
int country_id);
|
||||
|
||||
// Returns the names of providers that have been remotely disabled, for use with
|
||||
// RemoveDisabledProviders().
|
||||
std::vector<std::string> GetDisabledProviders();
|
||||
|
||||
// Returns the subset of |providers| for which |DohProviderEntry::provider| is
|
||||
// not listed in |disabled_providers|.
|
||||
net::DohProviderEntry::List RemoveDisabledProviders(
|
||||
const net::DohProviderEntry::List& providers,
|
||||
const std::vector<std::string>& disabled_providers);
|
||||
|
||||
// Implements the whitespace-delimited group syntax for DoH templates.
|
||||
std::vector<base::StringPiece> SplitGroup(base::StringPiece group);
|
||||
|
||||
@ -28,6 +45,16 @@ std::vector<base::StringPiece> SplitGroup(base::StringPiece group);
|
||||
// stored preferences.
|
||||
bool IsValidGroup(base::StringPiece group);
|
||||
|
||||
// When the selected template changes, call this function to update the
|
||||
// Selected, Unselected, and Ignored histograms for all the included providers,
|
||||
// and also for the custom provider option. If the old or new selection is the
|
||||
// custom provider option, pass an empty string as the template.
|
||||
void UpdateDropdownHistograms(const net::DohProviderEntry::List& providers,
|
||||
base::StringPiece old_template,
|
||||
base::StringPiece new_template);
|
||||
void UpdateValidationHistogram(bool valid);
|
||||
void UpdateProbeHistogram(bool success);
|
||||
|
||||
// Modifies |overrides| to use the DoH server specified by |server_template|.
|
||||
void ApplyTemplate(net::DnsConfigOverrides* overrides,
|
||||
base::StringPiece server_template);
|
||||
|
@ -6,12 +6,15 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/test/metrics/histogram_tester.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "chrome/common/chrome_features.h"
|
||||
#include "components/country_codes/country_codes.h"
|
||||
#include "components/embedder_support/pref_names.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
#include "components/prefs/testing_pref_service.h"
|
||||
#include "net/dns/dns_config_overrides.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
#include "testing/gmock/include/gmock/gmock-matchers.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
@ -27,7 +30,7 @@ const char kAlternateErrorPagesBackup[] = "alternate_error_pages.backup";
|
||||
|
||||
namespace secure_dns {
|
||||
|
||||
class DNSUtilTest : public testing::Test {
|
||||
class SecureDnsUtilTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override { DisableRedesign(); }
|
||||
|
||||
@ -43,7 +46,7 @@ class DNSUtilTest : public testing::Test {
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
};
|
||||
|
||||
TEST_F(DNSUtilTest, MigrateProbesPref) {
|
||||
TEST_F(SecureDnsUtilTest, MigrateProbesPref) {
|
||||
TestingPrefServiceSimple prefs;
|
||||
prefs.registry()->RegisterBooleanPref(
|
||||
embedder_support::kAlternateErrorPagesEnabled, true);
|
||||
@ -150,14 +153,14 @@ TEST_F(DNSUtilTest, MigrateProbesPref) {
|
||||
EXPECT_FALSE(backup_pref->HasUserSetting());
|
||||
}
|
||||
|
||||
TEST(DNSUtil, SplitGroup) {
|
||||
TEST(SecureDnsUtil, SplitGroup) {
|
||||
EXPECT_THAT(SplitGroup("a"), ElementsAre("a"));
|
||||
EXPECT_THAT(SplitGroup("a b"), ElementsAre("a", "b"));
|
||||
EXPECT_THAT(SplitGroup("a \tb\nc"), ElementsAre("a", "b\nc"));
|
||||
EXPECT_THAT(SplitGroup(" \ta b\n"), ElementsAre("a", "b"));
|
||||
}
|
||||
|
||||
TEST(DNSUtil, IsValidGroup) {
|
||||
TEST(SecureDnsUtil, IsValidGroup) {
|
||||
EXPECT_TRUE(IsValidGroup(""));
|
||||
EXPECT_TRUE(IsValidGroup("https://valid"));
|
||||
EXPECT_TRUE(IsValidGroup("https://valid https://valid2"));
|
||||
@ -168,7 +171,7 @@ TEST(DNSUtil, IsValidGroup) {
|
||||
EXPECT_FALSE(IsValidGroup("invalid invalid2"));
|
||||
}
|
||||
|
||||
TEST(DNSUtil, ApplyDohTemplatePost) {
|
||||
TEST(SecureDnsUtil, ApplyDohTemplatePost) {
|
||||
std::string post_template("https://valid");
|
||||
net::DnsConfigOverrides overrides;
|
||||
ApplyTemplate(&overrides, post_template);
|
||||
@ -178,7 +181,7 @@ TEST(DNSUtil, ApplyDohTemplatePost) {
|
||||
{post_template, true /* use_post */}))));
|
||||
}
|
||||
|
||||
TEST(DNSUtil, ApplyDohTemplateGet) {
|
||||
TEST(SecureDnsUtil, ApplyDohTemplateGet) {
|
||||
std::string get_template("https://valid/{?dns}");
|
||||
net::DnsConfigOverrides overrides;
|
||||
ApplyTemplate(&overrides, get_template);
|
||||
@ -188,6 +191,105 @@ TEST(DNSUtil, ApplyDohTemplateGet) {
|
||||
{get_template, false /* use_post */}))));
|
||||
}
|
||||
|
||||
net::DohProviderEntry::List GetProvidersForTesting() {
|
||||
static const auto global1 = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_Global1", net::DohProviderIdForHistogram(-1), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://global1.provider/dns-query{?dns}",
|
||||
"Global Provider 1" /* ui_name */,
|
||||
"https://global1.provider/privacy_policy/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */);
|
||||
static const auto no_display = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_NoDisplay", net::DohProviderIdForHistogram(-2), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://nodisplay.provider/dns-query{?dns}",
|
||||
"No Display Provider" /* ui_name */,
|
||||
"https://nodisplay.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */);
|
||||
static const auto ee_fr = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_EE_FR", net::DohProviderIdForHistogram(-3), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://ee.fr.provider/dns-query{?dns}",
|
||||
"EE/FR Provider" /* ui_name */,
|
||||
"https://ee.fr.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */, {"EE", "FR"} /* display_countries */);
|
||||
static const auto fr = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_FR", net::DohProviderIdForHistogram(-4), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://fr.provider/dns-query{?dns}",
|
||||
"FR Provider" /* ui_name */,
|
||||
"https://fr.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */, {"FR"} /* display_countries */);
|
||||
static const auto global2 = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_Global2", net::DohProviderIdForHistogram(-5), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://global2.provider/dns-query{?dns}",
|
||||
"Global Provider 2" /* ui_name */,
|
||||
"https://global2.provider/privacy_policy/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */);
|
||||
return {&global1, &no_display, &ee_fr, &fr, &global2};
|
||||
}
|
||||
|
||||
TEST(SecureDnsUtil, LocalProviders) {
|
||||
const auto providers = GetProvidersForTesting();
|
||||
|
||||
const auto fr_providers = ProvidersForCountry(
|
||||
providers, country_codes::CountryStringToCountryID("FR"));
|
||||
EXPECT_THAT(fr_providers, ElementsAre(providers[0], providers[2],
|
||||
providers[3], providers[4]));
|
||||
|
||||
const auto ee_providers = ProvidersForCountry(
|
||||
providers, country_codes::CountryStringToCountryID("EE"));
|
||||
EXPECT_THAT(ee_providers,
|
||||
ElementsAre(providers[0], providers[2], providers[4]));
|
||||
|
||||
const auto us_providers = ProvidersForCountry(
|
||||
providers, country_codes::CountryStringToCountryID("US"));
|
||||
EXPECT_THAT(us_providers, ElementsAre(providers[0], providers[4]));
|
||||
|
||||
const auto unknown_providers =
|
||||
ProvidersForCountry(providers, country_codes::kCountryIDUnknown);
|
||||
EXPECT_THAT(unknown_providers, ElementsAre(providers[0], providers[4]));
|
||||
}
|
||||
|
||||
TEST(SecureDnsUtil, DisabledProviders) {
|
||||
base::test::ScopedFeatureList scoped_features;
|
||||
scoped_features.InitAndEnableFeatureWithParameters(
|
||||
features::kDnsOverHttps,
|
||||
{{"DisabledProviders", "Provider_Global2, , Provider_EE_FR,Unexpected"}});
|
||||
EXPECT_THAT(GetDisabledProviders(),
|
||||
ElementsAre("Provider_Global2", "Provider_EE_FR", "Unexpected"));
|
||||
}
|
||||
|
||||
TEST(SecureDnsUtil, RemoveDisabled) {
|
||||
const auto providers = GetProvidersForTesting();
|
||||
const auto filtered_providers = RemoveDisabledProviders(
|
||||
providers, {"Provider_Global2", "", "Provider_EE_FR", "Unexpected"});
|
||||
EXPECT_THAT(filtered_providers,
|
||||
ElementsAre(providers[0], providers[1], providers[3]));
|
||||
}
|
||||
|
||||
TEST(SecureDnsUtil, UpdateDropdownHistograms) {
|
||||
base::HistogramTester histograms;
|
||||
|
||||
const auto providers = GetProvidersForTesting();
|
||||
UpdateDropdownHistograms(providers, providers[4]->dns_over_https_template,
|
||||
providers[0]->dns_over_https_template);
|
||||
|
||||
const std::string kUmaBase = "Net.DNS.UI.DropdownSelectionEvent";
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Ignored", 4u);
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Selected", 1u);
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Unselected", 1u);
|
||||
}
|
||||
|
||||
TEST(SecureDnsUtil, UpdateDropdownHistogramsCustom) {
|
||||
base::HistogramTester histograms;
|
||||
|
||||
const auto providers = GetProvidersForTesting();
|
||||
UpdateDropdownHistograms(providers, std::string(),
|
||||
providers[2]->dns_over_https_template);
|
||||
|
||||
const std::string kUmaBase = "Net.DNS.UI.DropdownSelectionEvent";
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Ignored", 4u);
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Selected", 1u);
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Unselected", 1u);
|
||||
}
|
||||
|
||||
} // namespace secure_dns
|
||||
|
||||
} // namespace chrome_browser_net
|
||||
|
@ -189,7 +189,7 @@ Polymer({
|
||||
this.showRadioGroup_ =
|
||||
/** @type {boolean} */ (this.secureDnsToggle_.value);
|
||||
if (this.secureDnsRadio_ === SecureDnsMode.SECURE &&
|
||||
this.$.secureResolverSelect.value === 'custom') {
|
||||
!this.$.secureResolverSelect.value) {
|
||||
this.$.secureDnsInput.focus();
|
||||
}
|
||||
this.updateDnsPrefs_(
|
||||
@ -205,7 +205,7 @@ Polymer({
|
||||
*/
|
||||
onRadioSelectionChanged_: function(event) {
|
||||
if (event.detail.value === SecureDnsMode.SECURE &&
|
||||
this.$.secureResolverSelect.value === 'custom') {
|
||||
!this.$.secureResolverSelect.value) {
|
||||
this.$.secureDnsInput.focus();
|
||||
}
|
||||
this.updateDnsPrefs_(event.detail.value);
|
||||
@ -230,7 +230,7 @@ Polymer({
|
||||
// was not specified, the custom entry may be invalid or may not
|
||||
// have passed validation yet, and we should not update either the
|
||||
// underlying mode or templates prefs.
|
||||
if (this.$.secureResolverSelect.value === 'custom') {
|
||||
if (!this.$.secureResolverSelect.value) {
|
||||
if (!templates) {
|
||||
return;
|
||||
}
|
||||
@ -276,7 +276,7 @@ Polymer({
|
||||
}
|
||||
this.updatePrivacyPolicyLine_();
|
||||
|
||||
if (this.$.secureResolverSelect.value === 'custom') {
|
||||
if (!this.$.secureResolverSelect.value) {
|
||||
this.$.secureDnsInput.focus();
|
||||
}
|
||||
|
||||
@ -362,8 +362,8 @@ Polymer({
|
||||
}
|
||||
|
||||
// Otherwise, select the custom option.
|
||||
this.$.secureResolverSelect.value = 'custom';
|
||||
this.lastResolverOption_ = 'custom';
|
||||
this.$.secureResolverSelect.value = '';
|
||||
this.lastResolverOption_ = '';
|
||||
|
||||
// Only update the custom input field if the templates are non-empty.
|
||||
// Otherwise, we may be clearing a previous value that the user wishes to
|
||||
@ -381,7 +381,7 @@ Polymer({
|
||||
updatePrivacyPolicyLine_: function() {
|
||||
// If the selected item is the custom provider option, hide the privacy
|
||||
// policy line.
|
||||
if (this.$.secureResolverSelect.value === 'custom') {
|
||||
if (!this.$.secureResolverSelect.value) {
|
||||
this.$.privacyPolicy.style.display = 'none';
|
||||
this.$.secureDnsInput.style.display = 'block';
|
||||
return;
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <utility>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/metrics/histogram_macros.h"
|
||||
#include "base/rand_util.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/net/secure_dns_config.h"
|
||||
@ -24,10 +23,12 @@
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_ui.h"
|
||||
#include "net/dns/public/dns_over_https_server_config.h"
|
||||
#include "net/dns/public/doh_provider_list.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
#include "net/dns/public/util.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
namespace secure_dns = chrome_browser_net::secure_dns;
|
||||
|
||||
namespace settings {
|
||||
|
||||
namespace {
|
||||
@ -57,11 +58,7 @@ std::unique_ptr<base::DictionaryValue> CreateSecureDnsSettingDict() {
|
||||
|
||||
} // namespace
|
||||
|
||||
SecureDnsHandler::SecureDnsHandler()
|
||||
: network_context_getter_(
|
||||
base::BindRepeating(&SecureDnsHandler::GetNetworkContext,
|
||||
base::Unretained(this))) {}
|
||||
|
||||
SecureDnsHandler::SecureDnsHandler() = default;
|
||||
SecureDnsHandler::~SecureDnsHandler() = default;
|
||||
|
||||
void SecureDnsHandler::RegisterMessages() {
|
||||
@ -111,38 +108,14 @@ void SecureDnsHandler::OnJavascriptDisallowed() {
|
||||
pref_registrar_.RemoveAll();
|
||||
}
|
||||
|
||||
base::Value SecureDnsHandler::GetSecureDnsResolverListForCountry(
|
||||
int country_id,
|
||||
const std::vector<net::DohProviderEntry>& providers) {
|
||||
std::vector<std::string> disabled_providers =
|
||||
SplitString(features::kDnsOverHttpsDisabledProvidersParam.Get(), ",",
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
|
||||
base::Value SecureDnsHandler::GetSecureDnsResolverList() {
|
||||
base::Value resolvers(base::Value::Type::LIST);
|
||||
resolver_histogram_map_.clear();
|
||||
// Add all non-disabled resolvers that should be displayed in |country_id|.
|
||||
for (const auto& entry : providers) {
|
||||
if (base::Contains(disabled_providers, entry.provider))
|
||||
continue;
|
||||
|
||||
if (entry.display_globally ||
|
||||
std::find_if(
|
||||
entry.display_countries.begin(), entry.display_countries.end(),
|
||||
[&country_id](const std::string& country_code) {
|
||||
return country_codes::CountryCharsToCountryID(
|
||||
country_code[0], country_code[1]) == country_id;
|
||||
}) != entry.display_countries.end()) {
|
||||
DCHECK(!entry.ui_name.empty());
|
||||
DCHECK(!entry.privacy_policy.empty());
|
||||
base::Value dict(base::Value::Type::DICTIONARY);
|
||||
dict.SetKey("name", base::Value(entry.ui_name));
|
||||
dict.SetKey("value", base::Value(entry.dns_over_https_template));
|
||||
dict.SetKey("policy", base::Value(entry.privacy_policy));
|
||||
resolvers.Append(std::move(dict));
|
||||
DCHECK(entry.provider_id_for_histogram.has_value());
|
||||
resolver_histogram_map_.insert({entry.dns_over_https_template,
|
||||
entry.provider_id_for_histogram.value()});
|
||||
}
|
||||
for (const auto* entry : providers_) {
|
||||
base::Value dict(base::Value::Type::DICTIONARY);
|
||||
dict.SetStringKey("name", entry->ui_name);
|
||||
dict.SetStringKey("value", entry->dns_over_https_template);
|
||||
dict.SetStringKey("policy", entry->privacy_policy);
|
||||
resolvers.Append(std::move(dict));
|
||||
}
|
||||
|
||||
// Randomize the order of the resolvers.
|
||||
@ -150,13 +123,10 @@ base::Value SecureDnsHandler::GetSecureDnsResolverListForCountry(
|
||||
|
||||
// Add a custom option to the front of the list
|
||||
base::Value custom(base::Value::Type::DICTIONARY);
|
||||
custom.SetKey("name",
|
||||
base::Value(l10n_util::GetStringUTF8(IDS_SETTINGS_CUSTOM)));
|
||||
custom.SetKey("value", base::Value("custom"));
|
||||
custom.SetKey("policy", base::Value(std::string()));
|
||||
custom.SetStringKey("name", l10n_util::GetStringUTF8(IDS_SETTINGS_CUSTOM));
|
||||
custom.SetStringKey("value", std::string()); // Empty value means custom.
|
||||
custom.SetStringKey("policy", std::string());
|
||||
resolvers.Insert(resolvers.GetList().begin(), std::move(custom));
|
||||
resolver_histogram_map_.insert(
|
||||
{"custom", net::DohProviderIdForHistogram::kCustom});
|
||||
|
||||
return resolvers;
|
||||
}
|
||||
@ -176,15 +146,18 @@ network::mojom::NetworkContext* SecureDnsHandler::GetNetworkContext() {
|
||||
->GetNetworkContext();
|
||||
}
|
||||
|
||||
void SecureDnsHandler::SetProvidersForTesting(
|
||||
net::DohProviderEntry::List providers) {
|
||||
providers_ = std::move(providers);
|
||||
}
|
||||
|
||||
void SecureDnsHandler::HandleGetSecureDnsResolverList(
|
||||
const base::ListValue* args) {
|
||||
AllowJavascript();
|
||||
std::string callback_id = args->GetList()[0].GetString();
|
||||
|
||||
ResolveJavascriptCallback(
|
||||
base::Value(callback_id),
|
||||
GetSecureDnsResolverListForCountry(country_codes::GetCurrentCountryID(),
|
||||
net::GetDohProviderList()));
|
||||
ResolveJavascriptCallback(base::Value(callback_id),
|
||||
GetSecureDnsResolverList());
|
||||
}
|
||||
|
||||
void SecureDnsHandler::HandleGetSecureDnsSetting(const base::ListValue* args) {
|
||||
@ -203,14 +176,12 @@ void SecureDnsHandler::HandleParseCustomDnsEntry(const base::ListValue* args) {
|
||||
|
||||
// Return all templates in the entry, or none if they are not all valid.
|
||||
base::Value templates(base::Value::Type::LIST);
|
||||
if (chrome_browser_net::secure_dns::IsValidGroup(custom_entry)) {
|
||||
for (base::StringPiece t :
|
||||
chrome_browser_net::secure_dns::SplitGroup(custom_entry)) {
|
||||
if (secure_dns::IsValidGroup(custom_entry)) {
|
||||
for (base::StringPiece t : secure_dns::SplitGroup(custom_entry)) {
|
||||
templates.Append(t);
|
||||
}
|
||||
}
|
||||
UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ValidationAttemptSuccess",
|
||||
!templates.GetList().empty());
|
||||
secure_dns::UpdateValidationHistogram(!templates.GetList().empty());
|
||||
ResolveJavascriptCallback(*callback_id, templates);
|
||||
}
|
||||
|
||||
@ -236,7 +207,7 @@ void SecureDnsHandler::HandleProbeCustomDnsTemplate(
|
||||
overrides.attempts = 1;
|
||||
overrides.randomize_ports = false;
|
||||
overrides.secure_dns_mode = net::DnsConfig::SecureDnsMode::SECURE;
|
||||
chrome_browser_net::secure_dns::ApplyTemplate(&overrides, server_template);
|
||||
secure_dns::ApplyTemplate(&overrides, server_template);
|
||||
DCHECK(!runner_);
|
||||
runner_ = std::make_unique<chrome_browser_net::DnsProbeRunner>(
|
||||
overrides, network_context_getter_);
|
||||
@ -251,29 +222,15 @@ void SecureDnsHandler::HandleRecordUserDropdownInteraction(
|
||||
std::string new_provider;
|
||||
CHECK(args->GetString(0, &old_provider));
|
||||
CHECK(args->GetString(1, &new_provider));
|
||||
DCHECK(resolver_histogram_map_.find(old_provider) !=
|
||||
resolver_histogram_map_.end());
|
||||
DCHECK(resolver_histogram_map_.find(new_provider) !=
|
||||
resolver_histogram_map_.end());
|
||||
for (auto& pair : resolver_histogram_map_) {
|
||||
if (pair.first == old_provider) {
|
||||
UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Unselected",
|
||||
pair.second);
|
||||
} else if (pair.first == new_provider) {
|
||||
UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Selected",
|
||||
pair.second);
|
||||
} else {
|
||||
UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Ignored",
|
||||
pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
secure_dns::UpdateDropdownHistograms(providers_, old_provider, new_provider);
|
||||
}
|
||||
|
||||
void SecureDnsHandler::OnProbeComplete() {
|
||||
bool success =
|
||||
runner_->result() == chrome_browser_net::DnsProbeRunner::CORRECT;
|
||||
runner_.reset();
|
||||
UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ProbeAttemptSuccess", success);
|
||||
secure_dns::UpdateProbeHistogram(success);
|
||||
ResolveJavascriptCallback(base::Value(probe_callback_id_),
|
||||
base::Value(success));
|
||||
probe_callback_id_.clear();
|
||||
@ -284,4 +241,12 @@ void SecureDnsHandler::SendSecureDnsSettingUpdatesToJavascript() {
|
||||
*CreateSecureDnsSettingDict());
|
||||
}
|
||||
|
||||
// static
|
||||
net::DohProviderEntry::List SecureDnsHandler::GetFilteredProviders() {
|
||||
const auto local_providers = secure_dns::ProvidersForCountry(
|
||||
net::DohProviderEntry::GetList(), country_codes::GetCurrentCountryID());
|
||||
return secure_dns::RemoveDisabledProviders(
|
||||
local_providers, secure_dns::GetDisabledProviders());
|
||||
}
|
||||
|
||||
} // namespace settings
|
||||
|
@ -9,12 +9,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/values.h"
|
||||
#include "chrome/browser/net/dns_probe_runner.h"
|
||||
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
|
||||
#include "components/prefs/pref_change_registrar.h"
|
||||
#include "net/dns/public/doh_provider_list.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
#include "services/network/public/cpp/resolve_host_client_base.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
|
||||
@ -35,13 +36,15 @@ class SecureDnsHandler : public SettingsPageUIHandler {
|
||||
// as a dictionary with the following keys: "name" (the text to display in the
|
||||
// UI), "value" (the DoH template for this provider), and "policy" (the URL of
|
||||
// the provider's privacy policy).
|
||||
base::Value GetSecureDnsResolverListForCountry(
|
||||
int country_id,
|
||||
const std::vector<net::DohProviderEntry>& providers);
|
||||
base::Value GetSecureDnsResolverList();
|
||||
|
||||
void SetNetworkContextForTesting(
|
||||
network::mojom::NetworkContext* network_context);
|
||||
|
||||
// DohProviderEntry cannot be copied, so the entries referenced in |providers|
|
||||
// must be long-lived.
|
||||
void SetProvidersForTesting(net::DohProviderEntry::List providers);
|
||||
|
||||
protected:
|
||||
// Retrieves all pre-approved secure resolvers and returns them to WebUI.
|
||||
void HandleGetSecureDnsResolverList(const base::ListValue* args);
|
||||
@ -66,10 +69,14 @@ class SecureDnsHandler : public SettingsPageUIHandler {
|
||||
network::mojom::NetworkContext* GetNetworkContext();
|
||||
void OnProbeComplete();
|
||||
|
||||
std::map<std::string, net::DohProviderIdForHistogram> resolver_histogram_map_;
|
||||
static net::DohProviderEntry::List GetFilteredProviders();
|
||||
|
||||
net::DohProviderEntry::List providers_ = GetFilteredProviders();
|
||||
std::unique_ptr<chrome_browser_net::DnsProbeRunner> runner_;
|
||||
chrome_browser_net::DnsProbeRunner::NetworkContextGetter
|
||||
network_context_getter_;
|
||||
network_context_getter_ =
|
||||
base::BindRepeating(&SecureDnsHandler::GetNetworkContext,
|
||||
base::Unretained(this));
|
||||
// ID of the Javascript callback for the current pending probe, or "" if
|
||||
// there is no probe currently in progress.
|
||||
std::string probe_callback_id_;
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "base/win/win_util.h"
|
||||
#endif
|
||||
|
||||
using net::DohProviderEntry;
|
||||
using testing::_;
|
||||
using testing::IsEmpty;
|
||||
using testing::Return;
|
||||
@ -43,47 +42,38 @@ constexpr char kRecordUserDropdownInteraction[] =
|
||||
"recordUserDropdownInteraction";
|
||||
constexpr char kWebUiFunctionName[] = "webUiCallbackName";
|
||||
|
||||
const std::vector<DohProviderEntry>& GetDohProviderListForTesting() {
|
||||
static const base::NoDestructor<std::vector<DohProviderEntry>> test_providers{
|
||||
{
|
||||
DohProviderEntry(
|
||||
"Provider_Global1", net::DohProviderIdForHistogram(-1),
|
||||
{} /*ip_strs */, {} /* dot_hostnames */,
|
||||
"https://global1.provider/dns-query{?dns}",
|
||||
"Global Provider 1" /* ui_name */,
|
||||
"https://global1.provider/privacy_policy/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"Provider_NoDisplay", net::DohProviderIdForHistogram(-2),
|
||||
{} /*ip_strs */, {} /* dot_hostnames */,
|
||||
"https://nodisplay.provider/dns-query{?dns}",
|
||||
"No Display Provider" /* ui_name */,
|
||||
"https://nodisplay.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"Provider_EE_FR", net::DohProviderIdForHistogram(-3),
|
||||
{} /*ip_strs */, {} /* dot_hostnames */,
|
||||
"https://ee.fr.provider/dns-query{?dns}",
|
||||
"EE/FR Provider" /* ui_name */,
|
||||
"https://ee.fr.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */,
|
||||
{"EE", "FR"} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"Provider_FR", net::DohProviderIdForHistogram(-4),
|
||||
{} /*ip_strs */, {} /* dot_hostnames */,
|
||||
"https://fr.provider/dns-query{?dns}",
|
||||
"FR Provider" /* ui_name */,
|
||||
"https://fr.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */, {"FR"} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"Provider_Global2", net::DohProviderIdForHistogram(-5),
|
||||
{} /*ip_strs */, {} /* dot_hostnames */,
|
||||
"https://global2.provider/dns-query{?dns}",
|
||||
"Global Provider 2" /* ui_name */,
|
||||
"https://global2.provider/privacy_policy/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
}};
|
||||
return *test_providers;
|
||||
net::DohProviderEntry::List GetDohProviderListForTesting() {
|
||||
static const auto global1 = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_Global1", net::DohProviderIdForHistogram(-1), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://global1.provider/dns-query{?dns}",
|
||||
"Global Provider 1" /* ui_name */,
|
||||
"https://global1.provider/privacy_policy/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */);
|
||||
static const auto no_display = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_NoDisplay", net::DohProviderIdForHistogram(-2), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://nodisplay.provider/dns-query{?dns}",
|
||||
"No Display Provider" /* ui_name */,
|
||||
"https://nodisplay.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */);
|
||||
static const auto ee_fr = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_EE_FR", net::DohProviderIdForHistogram(-3), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://ee.fr.provider/dns-query{?dns}",
|
||||
"EE/FR Provider" /* ui_name */,
|
||||
"https://ee.fr.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */, {"EE", "FR"} /* display_countries */);
|
||||
static const auto fr = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_FR", net::DohProviderIdForHistogram(-4), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://fr.provider/dns-query{?dns}",
|
||||
"FR Provider" /* ui_name */,
|
||||
"https://fr.provider/privacy_policy/" /* privacy_policy */,
|
||||
false /* display_globally */, {"FR"} /* display_countries */);
|
||||
static const auto global2 = net::DohProviderEntry::ConstructForTesting(
|
||||
"Provider_Global2", net::DohProviderIdForHistogram(-5), {} /*ip_strs */,
|
||||
{} /* dot_hostnames */, "https://global2.provider/dns-query{?dns}",
|
||||
"Global Provider 2" /* ui_name */,
|
||||
"https://global2.provider/privacy_policy/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */);
|
||||
return {&global1, &no_display, &ee_fr, &fr, &global2};
|
||||
}
|
||||
|
||||
bool FindDropdownItem(const base::Value& resolvers,
|
||||
@ -315,116 +305,40 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownList) {
|
||||
// Check results.
|
||||
base::Value::ConstListView resolver_list = call_data.arg3()->GetList();
|
||||
ASSERT_GE(resolver_list.size(), 1U);
|
||||
EXPECT_EQ("custom", resolver_list[0].FindKey("value")->GetString());
|
||||
EXPECT_TRUE(resolver_list[0].FindKey("value")->GetString().empty());
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownListForCountry) {
|
||||
// The 'EE' list should start with the custom entry, followed by the two
|
||||
// global providers and the 'EE' provider in some random order.
|
||||
base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry(
|
||||
country_codes::CountryCharsToCountryID('E', 'E'),
|
||||
GetDohProviderListForTesting());
|
||||
EXPECT_EQ(4u, resolver_list.GetList().size());
|
||||
EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString());
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1",
|
||||
"https://global1.provider/dns-query{?dns}",
|
||||
"https://global1.provider/privacy_policy/"));
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2",
|
||||
"https://global2.provider/dns-query{?dns}",
|
||||
"https://global2.provider/privacy_policy/"));
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "EE/FR Provider",
|
||||
"https://ee.fr.provider/dns-query{?dns}",
|
||||
"https://ee.fr.provider/privacy_policy/"));
|
||||
IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownListContents) {
|
||||
const auto entries = GetDohProviderListForTesting();
|
||||
handler_->SetProvidersForTesting(entries);
|
||||
const base::Value resolver_list = handler_->GetSecureDnsResolverList();
|
||||
|
||||
// The 'FR' list should start with the custom entry, followed by the two
|
||||
// global providers and the two 'FR' providers in some random order.
|
||||
resolver_list = handler_->GetSecureDnsResolverListForCountry(
|
||||
country_codes::CountryCharsToCountryID('F', 'R'),
|
||||
GetDohProviderListForTesting());
|
||||
EXPECT_EQ(5u, resolver_list.GetList().size());
|
||||
EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString());
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1",
|
||||
"https://global1.provider/dns-query{?dns}",
|
||||
"https://global1.provider/privacy_policy/"));
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2",
|
||||
"https://global2.provider/dns-query{?dns}",
|
||||
"https://global2.provider/privacy_policy/"));
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "EE/FR Provider",
|
||||
"https://ee.fr.provider/dns-query{?dns}",
|
||||
"https://ee.fr.provider/privacy_policy/"));
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "FR Provider",
|
||||
"https://fr.provider/dns-query{?dns}",
|
||||
"https://fr.provider/privacy_policy/"));
|
||||
|
||||
// The 'CA' list should start with the custom entry, followed by the two
|
||||
// global providers.
|
||||
resolver_list = handler_->GetSecureDnsResolverListForCountry(
|
||||
country_codes::CountryCharsToCountryID('C', 'A'),
|
||||
GetDohProviderListForTesting());
|
||||
EXPECT_EQ(3u, resolver_list.GetList().size());
|
||||
EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString());
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1",
|
||||
"https://global1.provider/dns-query{?dns}",
|
||||
"https://global1.provider/privacy_policy/"));
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2",
|
||||
"https://global2.provider/dns-query{?dns}",
|
||||
"https://global2.provider/privacy_policy/"));
|
||||
EXPECT_EQ(entries.size() + 1, resolver_list.GetList().size());
|
||||
EXPECT_TRUE(resolver_list.GetList()[0].FindKey("value")->GetString().empty());
|
||||
for (const auto* entry : entries) {
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, entry->ui_name,
|
||||
entry->dns_over_https_template,
|
||||
entry->privacy_policy));
|
||||
}
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownListChange) {
|
||||
// Populate the map for recording dropdown change metrics.
|
||||
base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry(
|
||||
country_codes::CountryCharsToCountryID('E', 'E'),
|
||||
GetDohProviderListForTesting());
|
||||
EXPECT_EQ(4u, resolver_list.GetList().size());
|
||||
handler_->SetProvidersForTesting(GetDohProviderListForTesting());
|
||||
|
||||
base::HistogramTester histograms;
|
||||
base::ListValue args;
|
||||
args.AppendString("custom" /* old_provider */);
|
||||
args.AppendString(std::string() /* old_provider */);
|
||||
args.AppendString(
|
||||
"https://global1.provider/dns-query{?dns}" /* new_provider */);
|
||||
web_ui_.HandleReceivedMessage(kRecordUserDropdownInteraction, &args);
|
||||
|
||||
const std::string uma_base("Net.DNS.UI.DropdownSelectionEvent");
|
||||
histograms.ExpectTotalCount(uma_base + ".Ignored", 2u);
|
||||
histograms.ExpectTotalCount(uma_base + ".Selected", 1u);
|
||||
histograms.ExpectTotalCount(uma_base + ".Unselected", 1u);
|
||||
const std::string kUmaBase = "Net.DNS.UI.DropdownSelectionEvent";
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Ignored", 4u);
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Selected", 1u);
|
||||
histograms.ExpectTotalCount(kUmaBase + ".Unselected", 1u);
|
||||
}
|
||||
|
||||
class SecureDnsHandlerTestWithDisabledProviders : public SecureDnsHandlerTest {
|
||||
protected:
|
||||
SecureDnsHandlerTestWithDisabledProviders() {
|
||||
scoped_features_.InitAndEnableFeatureWithParameters(
|
||||
features::kDnsOverHttps,
|
||||
{{"DisabledProviders",
|
||||
"Provider_Global2, , Provider_EE_FR,Unexpected"}});
|
||||
}
|
||||
|
||||
private:
|
||||
base::test::ScopedFeatureList scoped_features_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SecureDnsHandlerTestWithDisabledProviders);
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders,
|
||||
DropdownListDisabledProviders) {
|
||||
// The 'FR' list should start with the custom entry, followed by the two
|
||||
// global providers and the two 'FR' providers in some random order.
|
||||
base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry(
|
||||
country_codes::CountryCharsToCountryID('F', 'R'),
|
||||
GetDohProviderListForTesting());
|
||||
EXPECT_EQ(3u, resolver_list.GetList().size());
|
||||
EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString());
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1",
|
||||
"https://global1.provider/dns-query{?dns}",
|
||||
"https://global1.provider/privacy_policy/"));
|
||||
EXPECT_TRUE(FindDropdownItem(resolver_list, "FR Provider",
|
||||
"https://fr.provider/dns-query{?dns}",
|
||||
"https://fr.provider/privacy_policy/"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders,
|
||||
SecureDnsTemplates) {
|
||||
IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsTemplates) {
|
||||
std::string good_post_template = "https://foo.test/";
|
||||
std::string good_get_template = "https://bar.test/dns-query{?dns}";
|
||||
std::string bad_template = "dns-query{?dns}";
|
||||
@ -433,6 +347,8 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders,
|
||||
std::vector<std::string> secure_dns_templates;
|
||||
int management_mode;
|
||||
PrefService* local_state = g_browser_process->local_state();
|
||||
local_state->SetString(prefs::kDnsOverHttpsMode,
|
||||
SecureDnsConfig::kModeAutomatic);
|
||||
local_state->SetString(prefs::kDnsOverHttpsTemplates, good_post_template);
|
||||
EXPECT_TRUE(GetLastSettingsChangedMessage(
|
||||
&secure_dns_mode, &secure_dns_templates, &management_mode));
|
||||
@ -458,15 +374,6 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders,
|
||||
&secure_dns_mode, &secure_dns_templates, &management_mode));
|
||||
EXPECT_EQ(1u, secure_dns_templates.size());
|
||||
EXPECT_EQ(good_post_template, secure_dns_templates[0]);
|
||||
|
||||
// Should still return a provider that was disabled.
|
||||
local_state->SetString(prefs::kDnsOverHttpsTemplates,
|
||||
"https://global2.provider/dns-query{?dns}");
|
||||
EXPECT_TRUE(GetLastSettingsChangedMessage(
|
||||
&secure_dns_mode, &secure_dns_templates, &management_mode));
|
||||
EXPECT_EQ(1u, secure_dns_templates.size());
|
||||
EXPECT_EQ("https://global2.provider/dns-query{?dns}",
|
||||
secure_dns_templates[0]);
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateValid) {
|
||||
|
@ -62,7 +62,7 @@ suite('SettingsSecureDnsInteractive', function() {
|
||||
|
||||
/** @type {!Array<!ResolverOption>} */
|
||||
const resolverList = [
|
||||
{name: 'Custom', value: 'custom', policy: ''},
|
||||
{name: 'Custom', value: '', policy: ''},
|
||||
{
|
||||
name: 'resolver1',
|
||||
value: 'resolver1_template',
|
||||
@ -192,7 +192,7 @@ suite('SettingsSecureDnsInteractive', function() {
|
||||
test('SecureDnsDropdownCustom', function() {
|
||||
webUIListenerCallback('secure-dns-setting-changed', {
|
||||
mode: SecureDnsMode.SECURE,
|
||||
templates: ['custom'],
|
||||
templates: [''],
|
||||
managementMode: SecureDnsUiManagementMode.NO_OVERRIDE,
|
||||
});
|
||||
flush();
|
||||
@ -202,7 +202,7 @@ suite('SettingsSecureDnsInteractive', function() {
|
||||
'none', getComputedStyle(testElement.$$('#privacyPolicy')).display);
|
||||
assertEquals(
|
||||
'block', getComputedStyle(testElement.$$('#secureDnsInput')).display);
|
||||
assertEquals('custom', testElement.$$('#secureDnsInput').value);
|
||||
assertEquals('', testElement.$$('#secureDnsInput').value);
|
||||
});
|
||||
|
||||
test('SecureDnsDropdownChangeInSecureMode', async function() {
|
||||
@ -242,11 +242,11 @@ suite('SettingsSecureDnsInteractive', function() {
|
||||
|
||||
// Change to custom
|
||||
testBrowserProxy.reset();
|
||||
dropdownMenu.value = 'custom';
|
||||
dropdownMenu.value = '';
|
||||
dropdownMenu.dispatchEvent(new Event('change'));
|
||||
args = await testBrowserProxy.whenCalled('recordUserDropdownInteraction');
|
||||
assertEquals(resolverList[2].value, args[0]);
|
||||
assertEquals('custom', args[1]);
|
||||
assertEquals('', args[1]);
|
||||
assertEquals(0, dropdownMenu.selectedIndex);
|
||||
assertEquals(
|
||||
'none', getComputedStyle(testElement.$$('#privacyPolicy')).display);
|
||||
@ -266,7 +266,7 @@ suite('SettingsSecureDnsInteractive', function() {
|
||||
dropdownMenu.value = resolverList[1].value;
|
||||
dropdownMenu.dispatchEvent(new Event('change'));
|
||||
args = await testBrowserProxy.whenCalled('recordUserDropdownInteraction');
|
||||
assertEquals('custom', args[0]);
|
||||
assertEquals('', args[0]);
|
||||
assertEquals(resolverList[1].value, args[1]);
|
||||
assertEquals(
|
||||
SecureDnsMode.SECURE, testElement.prefs.dns_over_https.mode.value);
|
||||
@ -274,11 +274,11 @@ suite('SettingsSecureDnsInteractive', function() {
|
||||
resolverList[1].value,
|
||||
testElement.prefs.dns_over_https.templates.value);
|
||||
testBrowserProxy.reset();
|
||||
dropdownMenu.value = 'custom';
|
||||
dropdownMenu.value = '';
|
||||
dropdownMenu.dispatchEvent(new Event('change'));
|
||||
args = await testBrowserProxy.whenCalled('recordUserDropdownInteraction');
|
||||
assertEquals(resolverList[1].value, args[0]);
|
||||
assertEquals('custom', args[1]);
|
||||
assertEquals('', args[1]);
|
||||
assertEquals('some_input', secureDnsInput.value);
|
||||
});
|
||||
|
||||
|
@ -112,16 +112,12 @@ int GeoIDToCountryID(GEOID geo_id) {
|
||||
|
||||
const char kCountryIDAtInstall[] = "countryid_at_install";
|
||||
|
||||
#if !defined(OS_WIN) && !defined(OS_MACOSX)
|
||||
|
||||
int CountryStringToCountryID(const std::string& country) {
|
||||
return (country.length() == 2)
|
||||
? CountryCharsToCountryIDWithUpdate(country[0], country[1])
|
||||
: kCountryIDUnknown;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int GetCountryIDFromPrefs(PrefService* prefs) {
|
||||
if (!prefs)
|
||||
return GetCurrentCountryID();
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "net/base/address_list.h"
|
||||
#include "net/base/url_util.h"
|
||||
#include "net/dns/public/dns_protocol.h"
|
||||
#include "net/dns/public/doh_provider_list.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
#include "net/dns/public/util.h"
|
||||
#include "net/third_party/uri_template/uri_template.h"
|
||||
#include "url/url_canon.h"
|
||||
@ -113,21 +113,21 @@ bool DNSDomainFromDot(const base::StringPiece& dotted,
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<const DohProviderEntry*> GetDohProviderEntriesFromNameservers(
|
||||
DohProviderEntry::List GetDohProviderEntriesFromNameservers(
|
||||
const std::vector<IPEndPoint>& dns_servers,
|
||||
const std::vector<std::string>& excluded_providers) {
|
||||
const std::vector<DohProviderEntry>& providers = GetDohProviderList();
|
||||
std::vector<const DohProviderEntry*> entries;
|
||||
const DohProviderEntry::List& providers = DohProviderEntry::GetList();
|
||||
DohProviderEntry::List entries;
|
||||
|
||||
for (const auto& server : dns_servers) {
|
||||
for (const auto& entry : providers) {
|
||||
if (base::Contains(excluded_providers, entry.provider))
|
||||
for (const auto* entry : providers) {
|
||||
if (base::Contains(excluded_providers, entry->provider))
|
||||
continue;
|
||||
|
||||
// DoH servers should only be added once.
|
||||
if (base::Contains(entry.ip_addresses, server.address()) &&
|
||||
!base::Contains(entries, &entry)) {
|
||||
entries.push_back(&entry);
|
||||
if (base::Contains(entry->ip_addresses, server.address()) &&
|
||||
!base::Contains(entries, entry)) {
|
||||
entries.push_back(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -311,23 +311,21 @@ DnsQueryType AddressFamilyToDnsQueryType(AddressFamily address_family) {
|
||||
std::vector<DnsOverHttpsServerConfig> GetDohUpgradeServersFromDotHostname(
|
||||
const std::string& dot_server,
|
||||
const std::vector<std::string>& excluded_providers) {
|
||||
const std::vector<DohProviderEntry>& entries = GetDohProviderList();
|
||||
std::vector<DnsOverHttpsServerConfig> doh_servers;
|
||||
|
||||
if (dot_server.empty())
|
||||
return doh_servers;
|
||||
|
||||
for (const auto& entry : entries) {
|
||||
if (base::Contains(excluded_providers, entry.provider))
|
||||
for (const auto* entry : DohProviderEntry::GetList()) {
|
||||
if (base::Contains(excluded_providers, entry->provider))
|
||||
continue;
|
||||
|
||||
if (base::Contains(entry.dns_over_tls_hostnames, dot_server)) {
|
||||
if (base::Contains(entry->dns_over_tls_hostnames, dot_server)) {
|
||||
std::string server_method;
|
||||
CHECK(dns_util::IsValidDohTemplate(entry.dns_over_https_template,
|
||||
CHECK(dns_util::IsValidDohTemplate(entry->dns_over_https_template,
|
||||
&server_method));
|
||||
doh_servers.push_back(DnsOverHttpsServerConfig(
|
||||
entry.dns_over_https_template, server_method == "POST"));
|
||||
break;
|
||||
doh_servers.emplace_back(entry->dns_over_https_template,
|
||||
server_method == "POST");
|
||||
}
|
||||
}
|
||||
return doh_servers;
|
||||
@ -336,38 +334,35 @@ std::vector<DnsOverHttpsServerConfig> GetDohUpgradeServersFromDotHostname(
|
||||
std::vector<DnsOverHttpsServerConfig> GetDohUpgradeServersFromNameservers(
|
||||
const std::vector<IPEndPoint>& dns_servers,
|
||||
const std::vector<std::string>& excluded_providers) {
|
||||
std::vector<const DohProviderEntry*> entries =
|
||||
const auto entries =
|
||||
GetDohProviderEntriesFromNameservers(dns_servers, excluded_providers);
|
||||
std::vector<DnsOverHttpsServerConfig> doh_servers;
|
||||
std::string server_method;
|
||||
for (const auto* entry : entries) {
|
||||
CHECK(dns_util::IsValidDohTemplate(entry->dns_over_https_template,
|
||||
&server_method));
|
||||
doh_servers.push_back(DnsOverHttpsServerConfig(
|
||||
entry->dns_over_https_template, server_method == "POST"));
|
||||
}
|
||||
doh_servers.reserve(entries.size());
|
||||
std::transform(entries.begin(), entries.end(),
|
||||
std::back_inserter(doh_servers), [](const auto* entry) {
|
||||
std::string server_method;
|
||||
CHECK(dns_util::IsValidDohTemplate(
|
||||
entry->dns_over_https_template, &server_method));
|
||||
return DnsOverHttpsServerConfig(
|
||||
entry->dns_over_https_template, server_method == "POST");
|
||||
});
|
||||
return doh_servers;
|
||||
}
|
||||
|
||||
std::string GetDohProviderIdForHistogramFromDohConfig(
|
||||
const DnsOverHttpsServerConfig& doh_server) {
|
||||
const std::vector<DohProviderEntry>& entries = GetDohProviderList();
|
||||
for (const auto& entry : entries) {
|
||||
if (doh_server.server_template == entry.dns_over_https_template) {
|
||||
return entry.provider;
|
||||
}
|
||||
}
|
||||
return "Other";
|
||||
const auto& entries = DohProviderEntry::GetList();
|
||||
const auto it =
|
||||
std::find_if(entries.begin(), entries.end(), [&](const auto* entry) {
|
||||
return entry->dns_over_https_template == doh_server.server_template;
|
||||
});
|
||||
return it != entries.end() ? (*it)->provider : "Other";
|
||||
}
|
||||
|
||||
std::string GetDohProviderIdForHistogramFromNameserver(
|
||||
const IPEndPoint& nameserver) {
|
||||
std::vector<const DohProviderEntry*> entries =
|
||||
GetDohProviderEntriesFromNameservers({nameserver}, {});
|
||||
if (entries.size() == 0)
|
||||
return "Other";
|
||||
else
|
||||
return entries[0]->provider;
|
||||
const auto entries = GetDohProviderEntriesFromNameservers({nameserver}, {});
|
||||
return entries.empty() ? "Other" : entries[0]->provider;
|
||||
}
|
||||
|
||||
std::string SecureDnsModeToString(
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "base/stl_util.h"
|
||||
#include "net/dns/public/dns_protocol.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace net {
|
||||
@ -183,20 +184,24 @@ TEST_F(DNSUtilTest, GetDohUpgradeServersFromNameservers) {
|
||||
|
||||
doh_servers = GetDohUpgradeServersFromNameservers(nameservers,
|
||||
std::vector<std::string>());
|
||||
EXPECT_EQ(3u, doh_servers.size());
|
||||
EXPECT_EQ("https://chrome.cloudflare-dns.com/dns-query",
|
||||
doh_servers[0].server_template);
|
||||
EXPECT_EQ("https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
|
||||
doh_servers[1].server_template);
|
||||
EXPECT_EQ("https://doh.cleanbrowsing.org/doh/security-filter{?dns}",
|
||||
doh_servers[2].server_template);
|
||||
EXPECT_THAT(
|
||||
doh_servers,
|
||||
testing::ElementsAre(
|
||||
DnsOverHttpsServerConfig(
|
||||
"https://chrome.cloudflare-dns.com/dns-query", true),
|
||||
DnsOverHttpsServerConfig(
|
||||
"https://doh.cleanbrowsing.org/doh/family-filter{?dns}", false),
|
||||
DnsOverHttpsServerConfig(
|
||||
"https://doh.cleanbrowsing.org/doh/security-filter{?dns}",
|
||||
false)));
|
||||
|
||||
doh_servers = GetDohUpgradeServersFromNameservers(
|
||||
nameservers, std::vector<std::string>(
|
||||
{"CleanBrowsingSecure", "Cloudflare", "Unexpected"}));
|
||||
EXPECT_EQ(1u, doh_servers.size());
|
||||
EXPECT_EQ("https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
|
||||
doh_servers[0].server_template);
|
||||
EXPECT_THAT(
|
||||
doh_servers,
|
||||
testing::ElementsAre(DnsOverHttpsServerConfig(
|
||||
"https://doh.cleanbrowsing.org/doh/family-filter{?dns}", false)));
|
||||
}
|
||||
|
||||
TEST_F(DNSUtilTest, GetDohProviderIdForHistogramFromDohConfig) {
|
||||
|
@ -19,8 +19,8 @@ source_set("public") {
|
||||
"dns_protocol.h",
|
||||
"dns_query_type.cc",
|
||||
"dns_query_type.h",
|
||||
"doh_provider_list.cc",
|
||||
"doh_provider_list.h",
|
||||
"doh_provider_entry.cc",
|
||||
"doh_provider_entry.h",
|
||||
"resolve_error_info.cc",
|
||||
"resolve_error_info.h",
|
||||
"util.cc",
|
||||
@ -35,7 +35,7 @@ source_set("public") {
|
||||
source_set("tests") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"doh_provider_list_unittest.cc",
|
||||
"doh_provider_entry_unittest.cc",
|
||||
"util_unittest.cc",
|
||||
]
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "net/dns/public/doh_provider_list.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
@ -12,10 +12,189 @@
|
||||
|
||||
namespace net {
|
||||
|
||||
namespace {
|
||||
|
||||
std::set<IPAddress> ParseIPs(const std::set<base::StringPiece>& ip_strs) {
|
||||
std::set<IPAddress> ip_addresses;
|
||||
for (base::StringPiece ip_str : ip_strs) {
|
||||
IPAddress ip_address;
|
||||
bool success = ip_address.AssignFromIPLiteral(ip_str);
|
||||
DCHECK(success);
|
||||
ip_addresses.insert(std::move(ip_address));
|
||||
}
|
||||
return ip_addresses;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
const DohProviderEntry::List& DohProviderEntry::GetList() {
|
||||
// The provider names in these entries should be kept in sync with the
|
||||
// DohProviderId histogram suffix list in
|
||||
// tools/metrics/histograms/histograms.xml.
|
||||
static const base::NoDestructor<DohProviderEntry::List> providers{{
|
||||
new DohProviderEntry(
|
||||
"CleanBrowsingAdult", base::nullopt /* provider_id_for_histogram */,
|
||||
{"185.228.168.10", "185.228.169.11", "2a0d:2a00:1::1",
|
||||
"2a0d:2a00:2::1"},
|
||||
{"adult-filter-dns.cleanbrowsing.org"} /* dot_hostnames */,
|
||||
"https://doh.cleanbrowsing.org/doh/adult-filter{?dns}",
|
||||
"" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"CleanBrowsingFamily",
|
||||
DohProviderIdForHistogram::kCleanBrowsingFamily,
|
||||
{"185.228.168.168", "185.228.169.168",
|
||||
"2a0d:2a00:1::", "2a0d:2a00:2::"},
|
||||
{"family-filter-dns.cleanbrowsing.org"} /* dot_hostnames */,
|
||||
"https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
|
||||
"CleanBrowsing (Family Filter)" /* ui_name */,
|
||||
"https://cleanbrowsing.org/privacy" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"CleanBrowsingSecure", base::nullopt /* provider_id_for_histogram */,
|
||||
{"185.228.168.9", "185.228.169.9", "2a0d:2a00:1::2",
|
||||
"2a0d:2a00:2::2"},
|
||||
{"security-filter-dns.cleanbrowsing.org"} /* dot_hostnames */,
|
||||
"https://doh.cleanbrowsing.org/doh/security-filter{?dns}",
|
||||
"" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"Cloudflare", DohProviderIdForHistogram::kCloudflare,
|
||||
{"1.1.1.1", "1.0.0.1", "2606:4700:4700::1111",
|
||||
"2606:4700:4700::1001"},
|
||||
{"one.one.one.one",
|
||||
"1dot1dot1dot1.cloudflare-dns.com"} /* dns_over_tls_hostnames */,
|
||||
"https://chrome.cloudflare-dns.com/dns-query",
|
||||
"Cloudflare (1.1.1.1)" /* ui_name */,
|
||||
"https://developers.cloudflare.com/1.1.1.1/privacy/"
|
||||
"public-dns-resolver/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"Comcast", base::nullopt /* provider_id_for_histogram */,
|
||||
{"75.75.75.75", "75.75.76.76", "2001:558:feed::1",
|
||||
"2001:558:feed::2"},
|
||||
{"dot.xfinity.com"} /* dns_over_tls_hostnames */,
|
||||
"https://doh.xfinity.com/dns-query{?dns}", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"Cznic", base::nullopt /* provider_id_for_histogram */,
|
||||
{"185.43.135.1", "2001:148f:fffe::1"},
|
||||
{"odvr.nic.cz"} /* dns_over_tls_hostnames */,
|
||||
"https://odvr.nic.cz/doh", "" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */),
|
||||
// Note: DNS.SB has separate entries for autoupgrade and settings UI to
|
||||
// allow the extra |no_ecs| parameter for autoupgrade. This parameter
|
||||
// disables EDNS Client Subnet (ECS) handling in order to match the
|
||||
// behavior of the upgraded-from classic DNS server.
|
||||
new DohProviderEntry(
|
||||
"Dnssb", base::nullopt /* provider_id_for_histogram */,
|
||||
{"185.222.222.222", "185.184.222.222", "2a09::", "2a09::1"},
|
||||
{"dns.sb"} /* dns_over_tls_hostnames */,
|
||||
"https://doh.dns.sb/dns-query?no_ecs=true{&dns}", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"DnssbUserSelected", DohProviderIdForHistogram::kDnsSb,
|
||||
{} /* ip_strs */, {} /* dns_over_tls_hostnames */,
|
||||
"https://doh.dns.sb/dns-query{?dns}", "DNS.SB" /* ui_name */,
|
||||
"https://dns.sb/privacy/" /* privacy_policy */,
|
||||
false /* display_globally */, {"EE", "DE"} /* display_countries */),
|
||||
new DohProviderEntry("Google", DohProviderIdForHistogram::kGoogle,
|
||||
{"8.8.8.8", "8.8.4.4", "2001:4860:4860::8888",
|
||||
"2001:4860:4860::8844"},
|
||||
{"dns.google", "dns.google.com",
|
||||
"8888.google"} /* dns_over_tls_hostnames */,
|
||||
"https://dns.google/dns-query{?dns}",
|
||||
"Google (Public DNS)" /* ui_name */,
|
||||
"https://developers.google.com/speed/public-dns/"
|
||||
"privacy" /* privacy_policy */,
|
||||
true /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
new DohProviderEntry("Iij", DohProviderIdForHistogram::kIij,
|
||||
{} /* ip_strs */, {} /* dns_over_tls_hostnames */,
|
||||
"https://public.dns.iij.jp/dns-query",
|
||||
"IIJ (Public DNS)" /* ui_name */,
|
||||
"https://public.dns.iij.jp/" /* privacy_policy */,
|
||||
false /* display_globally */,
|
||||
{"JP"} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"OpenDNS", base::nullopt /* provider_id_for_histogram */,
|
||||
{"208.67.222.222", "208.67.220.220", "2620:119:35::35",
|
||||
"2620:119:53::53"},
|
||||
{""} /* dns_over_tls_hostnames */,
|
||||
"https://doh.opendns.com/dns-query{?dns}", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"OpenDNSFamily", base::nullopt /* provider_id_for_histogram */,
|
||||
{"208.67.222.123", "208.67.220.123", "2620:119:35::123",
|
||||
"2620:119:53::123"},
|
||||
{""} /* dns_over_tls_hostnames */,
|
||||
"https://doh.familyshield.opendns.com/dns-query{?dns}",
|
||||
"" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"Quad9Cdn", base::nullopt /* provider_id_for_histogram */,
|
||||
{"9.9.9.11", "149.112.112.11", "2620:fe::11", "2620:fe::fe:11"},
|
||||
{"dns11.quad9.net"} /* dns_over_tls_hostnames */,
|
||||
"https://dns11.quad9.net/dns-query", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"Quad9Insecure", base::nullopt /* provider_id_for_histogram */,
|
||||
{"9.9.9.10", "149.112.112.10", "2620:fe::10", "2620:fe::fe:10"},
|
||||
{"dns10.quad9.net"} /* dns_over_tls_hostnames */,
|
||||
"https://dns10.quad9.net/dns-query", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"Quad9Secure", DohProviderIdForHistogram::kQuad9Secure,
|
||||
{"9.9.9.9", "149.112.112.112", "2620:fe::fe", "2620:fe::9"},
|
||||
{"dns.quad9.net", "dns9.quad9.net"} /* dns_over_tls_hostnames */,
|
||||
"https://dns.quad9.net/dns-query", "Quad9 (9.9.9.9)" /* ui_name */,
|
||||
"https://www.quad9.net/home/privacy/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
new DohProviderEntry(
|
||||
"Switch", base::nullopt /* provider_id_for_histogram */,
|
||||
{"130.59.31.251", "130.59.31.248", "2001:620:0:ff::2",
|
||||
"2001:620:0:ff::3"},
|
||||
{"dns.switch.ch"} /* dns_over_tls_hostnames */,
|
||||
"https://dns.switch.ch/dns-query", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
}};
|
||||
return *providers;
|
||||
}
|
||||
|
||||
// static
|
||||
DohProviderEntry DohProviderEntry::ConstructForTesting(
|
||||
std::string provider,
|
||||
base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
|
||||
std::set<base::StringPiece> 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) {
|
||||
return DohProviderEntry(provider, provider_id_for_histogram, ip_strs,
|
||||
dns_over_tls_hostnames, dns_over_https_template,
|
||||
ui_name, privacy_policy, display_globally,
|
||||
display_countries);
|
||||
}
|
||||
|
||||
DohProviderEntry::DohProviderEntry(DohProviderEntry&& other) = default;
|
||||
DohProviderEntry& DohProviderEntry::operator=(DohProviderEntry&& other) =
|
||||
default;
|
||||
|
||||
DohProviderEntry::~DohProviderEntry() = default;
|
||||
|
||||
DohProviderEntry::DohProviderEntry(
|
||||
std::string provider,
|
||||
base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
|
||||
std::set<std::string> ip_strs,
|
||||
std::set<base::StringPiece> ip_strs,
|
||||
std::set<std::string> dns_over_tls_hostnames,
|
||||
std::string dns_over_https_template,
|
||||
std::string ui_name,
|
||||
@ -24,6 +203,7 @@ DohProviderEntry::DohProviderEntry(
|
||||
std::set<std::string> display_countries)
|
||||
: provider(std::move(provider)),
|
||||
provider_id_for_histogram(std::move(provider_id_for_histogram)),
|
||||
ip_addresses(ParseIPs(ip_strs)),
|
||||
dns_over_tls_hostnames(std::move(dns_over_tls_hostnames)),
|
||||
dns_over_https_template(std::move(dns_over_https_template)),
|
||||
ui_name(std::move(ui_name)),
|
||||
@ -43,153 +223,6 @@ DohProviderEntry::DohProviderEntry(
|
||||
for (const auto& display_country : this->display_countries) {
|
||||
DCHECK_EQ(2u, display_country.size());
|
||||
}
|
||||
for (const std::string& ip_str : ip_strs) {
|
||||
IPAddress ip_address;
|
||||
bool success = ip_address.AssignFromIPLiteral(ip_str);
|
||||
DCHECK(success);
|
||||
ip_addresses.insert(ip_address);
|
||||
}
|
||||
}
|
||||
|
||||
DohProviderEntry::DohProviderEntry(const DohProviderEntry& other) = default;
|
||||
DohProviderEntry::~DohProviderEntry() = default;
|
||||
|
||||
const std::vector<DohProviderEntry>& GetDohProviderList() {
|
||||
// The provider names in these entries should be kept in sync with the
|
||||
// DohProviderId histogram suffix list in
|
||||
// tools/metrics/histograms/histograms.xml.
|
||||
static const base::NoDestructor<std::vector<DohProviderEntry>> providers{{
|
||||
DohProviderEntry(
|
||||
"CleanBrowsingAdult", base::nullopt /* provider_id_for_histogram */,
|
||||
{"185.228.168.10", "185.228.169.11", "2a0d:2a00:1::1",
|
||||
"2a0d:2a00:2::1"},
|
||||
{"adult-filter-dns.cleanbrowsing.org"} /* dot_hostnames */,
|
||||
"https://doh.cleanbrowsing.org/doh/adult-filter{?dns}",
|
||||
"" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"CleanBrowsingFamily",
|
||||
DohProviderIdForHistogram::kCleanBrowsingFamily,
|
||||
{"185.228.168.168", "185.228.169.168",
|
||||
"2a0d:2a00:1::", "2a0d:2a00:2::"},
|
||||
{"family-filter-dns.cleanbrowsing.org"} /* dot_hostnames */,
|
||||
"https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
|
||||
"CleanBrowsing (Family Filter)" /* ui_name */,
|
||||
"https://cleanbrowsing.org/privacy" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"CleanBrowsingSecure", base::nullopt /* provider_id_for_histogram */,
|
||||
{"185.228.168.9", "185.228.169.9", "2a0d:2a00:1::2",
|
||||
"2a0d:2a00:2::2"},
|
||||
{"security-filter-dns.cleanbrowsing.org"} /* dot_hostnames */,
|
||||
"https://doh.cleanbrowsing.org/doh/security-filter{?dns}",
|
||||
"" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"Cloudflare", DohProviderIdForHistogram::kCloudflare,
|
||||
{"1.1.1.1", "1.0.0.1", "2606:4700:4700::1111",
|
||||
"2606:4700:4700::1001"},
|
||||
{"one.one.one.one",
|
||||
"1dot1dot1dot1.cloudflare-dns.com"} /* dns_over_tls_hostnames */,
|
||||
"https://chrome.cloudflare-dns.com/dns-query",
|
||||
"Cloudflare (1.1.1.1)" /* ui_name */,
|
||||
"https://developers.cloudflare.com/1.1.1.1/privacy/"
|
||||
"public-dns-resolver/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry("Comcast", base::nullopt /* provider_id_for_histogram */,
|
||||
{"75.75.75.75", "75.75.76.76", "2001:558:feed::1",
|
||||
"2001:558:feed::2"},
|
||||
{"dot.xfinity.com"} /* dns_over_tls_hostnames */,
|
||||
"https://doh.xfinity.com/dns-query{?dns}",
|
||||
"" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
DohProviderEntry("Cznic", base::nullopt /* provider_id_for_histogram */,
|
||||
{"185.43.135.1", "2001:148f:fffe::1"},
|
||||
{"odvr.nic.cz"} /* dns_over_tls_hostnames */,
|
||||
"https://odvr.nic.cz/doh", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
// Note: DNS.SB has separate entries for autoupgrade and settings UI to
|
||||
// allow the extra |no_ecs| parameter for autoupgrade. This parameter
|
||||
// disables EDNS Client Subnet (ECS) handling in order to match the
|
||||
// behavior of the upgraded-from classic DNS server.
|
||||
DohProviderEntry(
|
||||
"Dnssb", base::nullopt /* provider_id_for_histogram */,
|
||||
{"185.222.222.222", "185.184.222.222", "2a09::", "2a09::1"},
|
||||
{"dns.sb"} /* dns_over_tls_hostnames */,
|
||||
"https://doh.dns.sb/dns-query?no_ecs=true{&dns}", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"DnssbUserSelected", DohProviderIdForHistogram::kDnsSb,
|
||||
{} /* ip_strs */, {} /* dns_over_tls_hostnames */,
|
||||
"https://doh.dns.sb/dns-query{?dns}", "DNS.SB" /* ui_name */,
|
||||
"https://dns.sb/privacy/" /* privacy_policy */,
|
||||
false /* display_globally */, {"EE", "DE"} /* display_countries */),
|
||||
DohProviderEntry("Google", DohProviderIdForHistogram::kGoogle,
|
||||
{"8.8.8.8", "8.8.4.4", "2001:4860:4860::8888",
|
||||
"2001:4860:4860::8844"},
|
||||
{"dns.google", "dns.google.com",
|
||||
"8888.google"} /* dns_over_tls_hostnames */,
|
||||
"https://dns.google/dns-query{?dns}",
|
||||
"Google (Public DNS)" /* ui_name */,
|
||||
"https://developers.google.com/speed/public-dns/"
|
||||
"privacy" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry("Iij", DohProviderIdForHistogram::kIij, {} /* ip_strs */,
|
||||
{} /* dns_over_tls_hostnames */,
|
||||
"https://public.dns.iij.jp/dns-query",
|
||||
"IIJ (Public DNS)" /* ui_name */,
|
||||
"https://public.dns.iij.jp/" /* privacy_policy */,
|
||||
false /* display_globally */,
|
||||
{"JP"} /* display_countries */),
|
||||
DohProviderEntry("OpenDNS", base::nullopt /* provider_id_for_histogram */,
|
||||
{"208.67.222.222", "208.67.220.220", "2620:119:35::35",
|
||||
"2620:119:53::53"},
|
||||
{""} /* dns_over_tls_hostnames */,
|
||||
"https://doh.opendns.com/dns-query{?dns}",
|
||||
"" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"OpenDNSFamily", base::nullopt /* provider_id_for_histogram */,
|
||||
{"208.67.222.123", "208.67.220.123", "2620:119:35::123",
|
||||
"2620:119:53::123"},
|
||||
{""} /* dns_over_tls_hostnames */,
|
||||
"https://doh.familyshield.opendns.com/dns-query{?dns}",
|
||||
"" /* ui_name */, "" /* privacy_policy */,
|
||||
false /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"Quad9Cdn", base::nullopt /* provider_id_for_histogram */,
|
||||
{"9.9.9.11", "149.112.112.11", "2620:fe::11", "2620:fe::fe:11"},
|
||||
{"dns11.quad9.net"} /* dns_over_tls_hostnames */,
|
||||
"https://dns11.quad9.net/dns-query", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"Quad9Insecure", base::nullopt /* provider_id_for_histogram */,
|
||||
{"9.9.9.10", "149.112.112.10", "2620:fe::10", "2620:fe::fe:10"},
|
||||
{"dns10.quad9.net"} /* dns_over_tls_hostnames */,
|
||||
"https://dns10.quad9.net/dns-query", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
DohProviderEntry(
|
||||
"Quad9Secure", DohProviderIdForHistogram::kQuad9Secure,
|
||||
{"9.9.9.9", "149.112.112.112", "2620:fe::fe", "2620:fe::9"},
|
||||
{"dns.quad9.net", "dns9.quad9.net"} /* dns_over_tls_hostnames */,
|
||||
"https://dns.quad9.net/dns-query", "Quad9 (9.9.9.9)" /* ui_name */,
|
||||
"https://www.quad9.net/home/privacy/" /* privacy_policy */,
|
||||
true /* display_globally */, {} /* display_countries */),
|
||||
DohProviderEntry("Switch", base::nullopt /* provider_id_for_histogram */,
|
||||
{"130.59.31.251", "130.59.31.248", "2001:620:0:ff::2",
|
||||
"2001:620:0:ff::3"},
|
||||
{"dns.switch.ch"} /* dns_over_tls_hostnames */,
|
||||
"https://dns.switch.ch/dns-query", "" /* ui_name */,
|
||||
"" /* privacy_policy */, false /* display_globally */,
|
||||
{} /* display_countries */),
|
||||
}};
|
||||
return *providers;
|
||||
}
|
||||
|
||||
} // namespace net
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef NET_DNS_PUBLIC_DOH_PROVIDER_LIST_H_
|
||||
#define NET_DNS_PUBLIC_DOH_PROVIDER_LIST_H_
|
||||
#ifndef NET_DNS_PUBLIC_DOH_PROVIDER_ENTRY_H_
|
||||
#define NET_DNS_PUBLIC_DOH_PROVIDER_ENTRY_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
@ -41,37 +41,56 @@ enum class DohProviderIdForHistogram {
|
||||
// codes, if any, where the entry is eligible for being displayed in the
|
||||
// dropdown menu.
|
||||
struct NET_EXPORT DohProviderEntry {
|
||||
DohProviderEntry(
|
||||
public:
|
||||
using List = std::vector<const DohProviderEntry*>;
|
||||
|
||||
std::string provider;
|
||||
// A provider_id_for_histogram is required for entries that are intended to
|
||||
// be visible in the UI.
|
||||
base::Optional<DohProviderIdForHistogram> provider_id_for_histogram;
|
||||
std::set<IPAddress> ip_addresses;
|
||||
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;
|
||||
|
||||
// Returns the full list of DoH providers. A subset of this list may be used
|
||||
// to support upgrade in automatic mode or to populate the dropdown menu for
|
||||
// secure mode.
|
||||
static const List& GetList();
|
||||
|
||||
static DohProviderEntry ConstructForTesting(
|
||||
std::string provider,
|
||||
base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
|
||||
std::set<std::string> ip_strs,
|
||||
std::set<base::StringPiece> 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);
|
||||
DohProviderEntry(const DohProviderEntry& other);
|
||||
|
||||
// Entries are move-only. This allows tests to construct a List but ensures
|
||||
// that |const DohProviderEntry*| is a safe type for application code.
|
||||
DohProviderEntry(DohProviderEntry&& other);
|
||||
DohProviderEntry& operator=(DohProviderEntry&& other);
|
||||
~DohProviderEntry();
|
||||
|
||||
const std::string provider;
|
||||
// A provider_id_for_histogram is required for entries that are intended to
|
||||
// be visible in the UI.
|
||||
const base::Optional<DohProviderIdForHistogram> provider_id_for_histogram;
|
||||
std::set<IPAddress> ip_addresses;
|
||||
const std::set<std::string> dns_over_tls_hostnames;
|
||||
const std::string dns_over_https_template;
|
||||
const std::string ui_name;
|
||||
const std::string privacy_policy;
|
||||
bool display_globally;
|
||||
std::set<std::string> display_countries;
|
||||
private:
|
||||
DohProviderEntry(
|
||||
std::string provider,
|
||||
base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
|
||||
std::set<base::StringPiece> 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);
|
||||
};
|
||||
|
||||
// Returns the full list of DoH providers. A subset of this list may be used
|
||||
// to support upgrade in automatic mode or to populate the dropdown menu for
|
||||
// secure mode.
|
||||
NET_EXPORT const std::vector<DohProviderEntry>& GetDohProviderList();
|
||||
|
||||
} // namespace net
|
||||
|
||||
#endif // NET_DNS_PUBLIC_DOH_PROVIDER_LIST_H_
|
||||
#endif // NET_DNS_PUBLIC_DOH_PROVIDER_ENTRY_H_
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "net/dns/public/doh_provider_list.h"
|
||||
#include "net/dns/public/doh_provider_entry.h"
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
@ -10,7 +10,7 @@ namespace net {
|
||||
namespace {
|
||||
|
||||
TEST(DohProviderListTest, GetDohProviderList) {
|
||||
const std::vector<DohProviderEntry>& list = GetDohProviderList();
|
||||
const DohProviderEntry::List& list = DohProviderEntry::GetList();
|
||||
EXPECT_FALSE(list.empty());
|
||||
}
|
||||
|
Reference in New Issue
Block a user