diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd
index b1fc3b0d743..10d6f8da5a3 100644
--- a/app/brave_generated_resources.grd
+++ b/app/brave_generated_resources.grd
@@ -694,6 +694,9 @@ By installing this extension, you are agreeing to the Google Widevine Terms of U
Allow Google login for extensions
+
+ Method to resolve Unstoppable Domains
+
Method to resolve IPFS resources
diff --git a/browser/BUILD.gn b/browser/BUILD.gn
index 688213df4c4..b93014a5e13 100644
--- a/browser/BUILD.gn
+++ b/browser/BUILD.gn
@@ -16,6 +16,7 @@ import("//brave/components/ipfs/buildflags/buildflags.gni")
import("//brave/components/sidebar/buildflags/buildflags.gni")
import("//brave/components/speedreader/buildflags.gni")
import("//brave/components/tor/buildflags/buildflags.gni")
+import("//brave/components/unstoppable_domains/buildflags/buildflags.gni")
import("//build/buildflag_header.gni")
import("//build/config/features.gni")
import("//chrome/common/features.gni")
@@ -154,6 +155,7 @@ source_set("browser_process") {
"//brave/components/sidebar/buildflags",
"//brave/components/speedreader:buildflags",
"//brave/components/tor/buildflags",
+ "//brave/components/unstoppable_domains/buildflags",
"//brave/components/weekly_storage",
"//brave/services/network/public/cpp",
"//brave/ui/brave_ads",
@@ -289,6 +291,17 @@ source_set("browser_process") {
]
}
+ if (unstoppable_domains_enabled) {
+ sources += [
+ "unstoppable_domains/unstoppable_domains_service_delegate_impl.cc",
+ "unstoppable_domains/unstoppable_domains_service_delegate_impl.h",
+ "unstoppable_domains/unstoppable_domains_service_factory.cc",
+ "unstoppable_domains/unstoppable_domains_service_factory.h",
+ ]
+
+ deps += [ "//brave/components/unstoppable_domains" ]
+ }
+
if (ipfs_enabled) {
sources += [
"ipfs/content_browser_client_helper.cc",
diff --git a/browser/brave_local_state_prefs.cc b/browser/brave_local_state_prefs.cc
index 42b92a71c26..667ee1120ca 100644
--- a/browser/brave_local_state_prefs.cc
+++ b/browser/brave_local_state_prefs.cc
@@ -18,6 +18,7 @@
#include "brave/components/p3a/brave_p3a_service.h"
#include "brave/components/p3a/buildflags.h"
#include "brave/components/tor/buildflags/buildflags.h"
+#include "brave/components/unstoppable_domains/buildflags/buildflags.h"
#include "chrome/common/pref_names.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/prefs/pref_registry_simple.h"
@@ -42,6 +43,10 @@
#include "brave/browser/widevine/widevine_utils.h"
#endif
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+#include "brave/components/unstoppable_domains/unstoppable_domains_service.h"
+#endif
+
namespace brave {
void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) {
@@ -95,6 +100,11 @@ void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
RegisterWidevineLocalstatePrefs(registry);
#endif
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+ unstoppable_domains::UnstoppableDomainsService::RegisterLocalStatePrefs(
+ registry);
+#endif
+
RegisterLocalStatePrefsForMigration(registry);
}
diff --git a/browser/extensions/BUILD.gn b/browser/extensions/BUILD.gn
index 0a95f5484c9..fe2f08ba484 100644
--- a/browser/extensions/BUILD.gn
+++ b/browser/extensions/BUILD.gn
@@ -10,6 +10,7 @@ import("//brave/components/gemini/browser/buildflags/buildflags.gni")
import("//brave/components/ipfs/buildflags/buildflags.gni")
import("//brave/components/sidebar/buildflags/buildflags.gni")
import("//brave/components/tor/buildflags/buildflags.gni")
+import("//brave/components/unstoppable_domains/buildflags/buildflags.gni")
import("//build/config/features.gni")
import("//components/gcm_driver/config.gni")
@@ -67,6 +68,7 @@ source_set("extensions") {
"//brave/components/ipfs/buildflags",
"//brave/components/sidebar/buildflags",
"//brave/components/tor/buildflags",
+ "//brave/components/unstoppable_domains/buildflags",
"//chrome/browser/extensions",
"//chrome/common",
"//components/gcm_driver:gcm_buildflags",
@@ -111,6 +113,10 @@ source_set("extensions") {
deps += [ "//brave/components/ipfs" ]
}
+ if (unstoppable_domains_enabled) {
+ deps += [ "//brave/components/unstoppable_domains" ]
+ }
+
if (brave_rewards_enabled) {
sources += [
"api/brave_rewards_api.cc",
diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc
index a626ca1a3f6..682c4c2767b 100644
--- a/browser/extensions/api/settings_private/brave_prefs_util.cc
+++ b/browser/extensions/api/settings_private/brave_prefs_util.cc
@@ -14,6 +14,7 @@
#include "brave/components/ntp_background_images/common/pref_names.h"
#include "brave/components/sidebar/buildflags/buildflags.h"
#include "brave/components/tor/buildflags/buildflags.h"
+#include "brave/components/unstoppable_domains/buildflags/buildflags.h"
#include "chrome/browser/extensions/api/settings_private/prefs_util.h"
#include "chrome/common/extensions/api/settings_private.h"
#include "chrome/common/pref_names.h"
@@ -45,6 +46,10 @@
#include "brave/components/tor/pref_names.h"
#endif
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+#include "brave/components/unstoppable_domains/pref_names.h"
+#endif
+
namespace extensions {
using ntp_background_images::prefs::kNewTabPageShowBackgroundImage;
@@ -207,6 +212,12 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() {
(*s_brave_allowlist)[prefs::kWebRTCIPHandlingPolicy] =
settings_api::PrefType::PREF_TYPE_STRING;
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+ // Unstoppable Domains pref
+ (*s_brave_allowlist)[unstoppable_domains::kResolveMethod] =
+ settings_api::PrefType::PREF_TYPE_NUMBER;
+#endif
+
return *s_brave_allowlist;
}
diff --git a/browser/profiles/BUILD.gn b/browser/profiles/BUILD.gn
index b714402d246..43138a45ec7 100644
--- a/browser/profiles/BUILD.gn
+++ b/browser/profiles/BUILD.gn
@@ -33,11 +33,11 @@ source_set("profiles") {
"//brave/components/brave_rewards/browser",
"//brave/components/brave_sync:prefs",
"//brave/components/brave_wallet/buildflags",
- "//brave/components/brave_wallet/buildflags",
"//brave/components/content_settings/core/browser",
"//brave/components/ipfs/buildflags",
"//brave/components/ntp_background_images/common",
"//brave/components/tor",
+ "//brave/components/unstoppable_domains/buildflags",
"//brave/content:browser",
"//chrome/common",
"//components/gcm_driver:gcm_buildflags",
diff --git a/browser/profiles/brave_profile_manager.cc b/browser/profiles/brave_profile_manager.cc
index 1c6d7a89524..64b7ddb880c 100644
--- a/browser/profiles/brave_profile_manager.cc
+++ b/browser/profiles/brave_profile_manager.cc
@@ -19,6 +19,7 @@
#include "brave/components/content_settings/core/browser/brave_content_settings_pref_provider.h"
#include "brave/components/ipfs/buildflags/buildflags.h"
#include "brave/components/tor/tor_constants.h"
+#include "brave/components/unstoppable_domains/buildflags/buildflags.h"
#include "brave/content/browser/webui/brave_shared_resources_data_source.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
@@ -50,6 +51,10 @@
#include "brave/browser/ipfs/ipfs_service_factory.h"
#endif
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+#include "brave/browser/unstoppable_domains/unstoppable_domains_service_factory.h"
+#endif
+
using content::BrowserThread;
BraveProfileManager::BraveProfileManager(const base::FilePath& user_data_dir)
@@ -108,6 +113,9 @@ void BraveProfileManager::DoFinalInitForServices(Profile* profile,
#if BUILDFLAG(IPFS_ENABLED)
ipfs::IpfsServiceFactory::GetForContext(profile);
#endif
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+ unstoppable_domains::UnstoppableDomainsServiceFactory::GetForContext(profile);
+#endif
#if !BUILDFLAG(USE_GCM_FROM_PLATFORM)
gcm::BraveGCMChannelStatus* status =
gcm::BraveGCMChannelStatus::GetForProfile(profile);
diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html
index c0d231e44e9..579fe7fbe7a 100644
--- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html
+++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html
@@ -85,6 +85,12 @@
sub-label="$i18n{hangoutsEnabledDesc}"
on-settings-boolean-control-change="onHangoutsEnabledChange_">
+
+
$i18n{resolveUnstoppableDomainsDesc}
+
+
UpdateNetworkService(false /* record_metrics */);
+}
+
+} // namespace unstoppable_domains
diff --git a/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h b/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h
new file mode 100644
index 00000000000..aed7638b453
--- /dev/null
+++ b/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_IMPL_H_
+#define BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_IMPL_H_
+
+#include "brave/components/unstoppable_domains/unstoppable_domains_service_delegate.h"
+
+namespace unstoppable_domains {
+
+class UnstoppableDomainsServiceDelegateImpl
+ : public UnstoppableDomainsServiceDelegate {
+ public:
+ UnstoppableDomainsServiceDelegateImpl() = default;
+ ~UnstoppableDomainsServiceDelegateImpl() override = default;
+
+ UnstoppableDomainsServiceDelegateImpl(
+ const UnstoppableDomainsServiceDelegateImpl&) = delete;
+ UnstoppableDomainsServiceDelegateImpl& operator=(
+ UnstoppableDomainsServiceDelegateImpl&) = delete;
+
+ void UpdateNetworkService() override;
+};
+
+} // namespace unstoppable_domains
+
+#endif // BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_IMPL_H_
diff --git a/browser/unstoppable_domains/unstoppable_domains_service_factory.cc b/browser/unstoppable_domains/unstoppable_domains_service_factory.cc
new file mode 100644
index 00000000000..909c1efc34f
--- /dev/null
+++ b/browser/unstoppable_domains/unstoppable_domains_service_factory.cc
@@ -0,0 +1,45 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "brave/browser/unstoppable_domains/unstoppable_domains_service_factory.h"
+
+#include
+
+#include "brave/browser/brave_browser_process_impl.h"
+#include "brave/browser/unstoppable_domains/unstoppable_domains_service_delegate_impl.h"
+#include "brave/components/unstoppable_domains/unstoppable_domains_service.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace unstoppable_domains {
+
+UnstoppableDomainsServiceFactory::UnstoppableDomainsServiceFactory()
+ : BrowserContextKeyedServiceFactory(
+ "UnstoppableDomainsService",
+ BrowserContextDependencyManager::GetInstance()) {}
+
+UnstoppableDomainsServiceFactory::~UnstoppableDomainsServiceFactory() {}
+
+// static
+UnstoppableDomainsServiceFactory*
+UnstoppableDomainsServiceFactory::GetInstance() {
+ return base::Singleton::get();
+}
+
+// static
+UnstoppableDomainsService* UnstoppableDomainsServiceFactory::GetForContext(
+ content::BrowserContext* context) {
+ return static_cast(
+ GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+KeyedService* UnstoppableDomainsServiceFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ return new UnstoppableDomainsService(
+ std::make_unique(), context,
+ g_brave_browser_process ? g_brave_browser_process->local_state()
+ : nullptr);
+}
+
+} // namespace unstoppable_domains
diff --git a/browser/unstoppable_domains/unstoppable_domains_service_factory.h b/browser/unstoppable_domains/unstoppable_domains_service_factory.h
new file mode 100644
index 00000000000..d64665f916e
--- /dev/null
+++ b/browser/unstoppable_domains/unstoppable_domains_service_factory.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_FACTORY_H_
+#define BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace unstoppable_domains {
+
+class UnstoppableDomainsService;
+
+class UnstoppableDomainsServiceFactory
+ : public BrowserContextKeyedServiceFactory {
+ public:
+ static UnstoppableDomainsService* GetForContext(
+ content::BrowserContext* context);
+ static UnstoppableDomainsServiceFactory* GetInstance();
+
+ private:
+ friend struct base::DefaultSingletonTraits;
+
+ UnstoppableDomainsServiceFactory();
+ ~UnstoppableDomainsServiceFactory() override;
+
+ UnstoppableDomainsServiceFactory(const UnstoppableDomainsServiceFactory&) =
+ delete;
+ UnstoppableDomainsServiceFactory& operator=(
+ const UnstoppableDomainsServiceFactory&) = delete;
+
+ // BrowserContextKeyedServiceFactory overrides:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+};
+
+} // namespace unstoppable_domains
+
+#endif // BRAVE_BROWSER_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_FACTORY_H_
diff --git a/chromium_src/chrome/browser/net/stub_resolver_config_reader.cc b/chromium_src/chrome/browser/net/stub_resolver_config_reader.cc
new file mode 100644
index 00000000000..916042f120e
--- /dev/null
+++ b/chromium_src/chrome/browser/net/stub_resolver_config_reader.cc
@@ -0,0 +1,47 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "base/strings/strcat.h"
+#include "brave/components/unstoppable_domains/buildflags/buildflags.h"
+#include "components/prefs/pref_service.h"
+
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+#include "brave/components/unstoppable_domains/constants.h"
+#include "brave/components/unstoppable_domains/pref_names.h"
+#endif
+
+namespace {
+
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+void AddUnstoppableDomainsResolver(std::string* doh_templates,
+ PrefService* local_state) {
+ bool resolve_ud_enabled =
+ local_state->FindPreference(unstoppable_domains::kResolveMethod) &&
+ local_state->GetInteger(unstoppable_domains::kResolveMethod) ==
+ static_cast(
+ unstoppable_domains::ResolveMethodTypes::DNS_OVER_HTTPS);
+
+ if (resolve_ud_enabled &&
+ doh_templates->find(unstoppable_domains::kDoHResolver) ==
+ std::string::npos) {
+ *doh_templates =
+ base::StrCat({unstoppable_domains::kDoHResolver, " ", *doh_templates});
+ }
+}
+#endif // BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+
+void AddDoHServers(std::string* doh_templates, PrefService* local_state) {
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+ AddUnstoppableDomainsResolver(doh_templates, local_state);
+#endif
+}
+
+} // namespace
+
+#define BRAVE_GET_AND_UPDATE_CONFIGURATION \
+ AddDoHServers(&doh_templates, local_state_);
+
+#include "../../../../../chrome/browser/net/stub_resolver_config_reader.cc"
+#undef BRAVE_GET_AND_UPDATE_CONFIGURATION
diff --git a/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 4d38033d27d..4a0281ce541 100644
--- a/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -219,6 +219,8 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_LOAD_CRYPTO_WALLETS_ON_STARTUP},
{"googleLoginForExtensionsDesc", IDS_SETTINGS_GOOGLE_LOGIN_FOR_EXTENSIONS},
{"hangoutsEnabledDesc", IDS_SETTINGS_HANGOUTS_ENABLED_DESC},
+ {"resolveUnstoppableDomainsDesc",
+ IDS_SETTINGS_RESOLVE_UNSTOPPABLE_DOMAINS_DESC},
{"resolveIPFSURLDesc", IDS_SETTINGS_RESOLVE_IPFS_URLS_DESC},
{"ipfsPublicGatewayDesc", IDS_SETTINGS_IPFS_PUBLIC_GATEWAY_DESC},
{"ipfsChangeGatewayButtonLabel",
diff --git a/chromium_src/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc b/chromium_src/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
new file mode 100644
index 00000000000..4b7687839f3
--- /dev/null
+++ b/chromium_src/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
@@ -0,0 +1,50 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "base/values.h"
+#include "brave/components/unstoppable_domains/buildflags/buildflags.h"
+
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+#include "brave/components/unstoppable_domains/constants.h"
+#endif
+
+namespace settings {
+namespace {
+std::unique_ptr CreateSecureDnsSettingDict();
+} // namespace
+} // namespace settings
+
+#include "../../../../../../../chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc"
+
+namespace settings {
+
+namespace {
+
+// Hide Unstoppable Domains resolver in the custom provider list in settings
+// because it will be used for name resolution only for TLDs from Unstoppable
+// Domains, instaed of a global DoH settings.
+std::unique_ptr CreateSecureDnsSettingDict() {
+ auto dict = CreateSecureDnsSettingDict_ChromiumImpl();
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+ if (!dict->FindListPath("templates")) {
+ return dict;
+ }
+
+ auto secure_dns_templates = std::make_unique();
+ for (const auto& template_str : dict->FindListPath("templates")->GetList()) {
+ if (!template_str.is_string())
+ return dict;
+ if (template_str.GetString() != unstoppable_domains::kDoHResolver)
+ secure_dns_templates->Append(template_str.GetString());
+ }
+
+ dict->SetList("templates", std::move(secure_dns_templates));
+#endif // BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+ return dict;
+}
+
+} // namespace
+
+} // namespace settings
diff --git a/chromium_src/net/dns/dns_transaction.cc b/chromium_src/net/dns/dns_transaction.cc
new file mode 100644
index 00000000000..085f7326703
--- /dev/null
+++ b/chromium_src/net/dns/dns_transaction.cc
@@ -0,0 +1,47 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "base/strings/string_util.h"
+#include "brave/components/unstoppable_domains/buildflags/buildflags.h"
+#include "net/dns/dns_config.h"
+#include "net/dns/dns_server_iterator.h"
+
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+#include "brave/components/unstoppable_domains/constants.h"
+#endif
+
+namespace {
+
+bool GetNextIndex(const std::string& hostname,
+ const net::DnsConfig& config,
+ net::DnsServerIterator* dns_server_iterator,
+ size_t* doh_server_index) {
+#if BUILDFLAG(UNSTOPPABLE_DOMAINS_ENABLED)
+ // Skip unstoppable domains resolver for non-crypto domains.
+ if (!base::EndsWith(hostname, unstoppable_domains::kCryptoDomain) &&
+ config.dns_over_https_servers[*doh_server_index].server_template ==
+ unstoppable_domains::kDoHResolver) {
+ // No next available index to attempt.
+ if (!dns_server_iterator->AttemptAvailable()) {
+ return false;
+ }
+
+ *doh_server_index = dns_server_iterator->GetNextAttemptIndex();
+ }
+#endif
+
+ return true;
+}
+
+} // namespace
+
+#define BRAVE_MAKE_HTTP_ATTEMPT \
+ if (!GetNextIndex(hostname_, session_.get()->config(), \
+ dns_server_iterator_.get(), &doh_server_index)) { \
+ return AttemptResult(ERR_BLOCKED_BY_CLIENT, nullptr); \
+ }
+
+#include "../../../../net/dns/dns_transaction.cc"
+#undef BRAVE_MAKE_HTTP_ATTEMPT
diff --git a/components/unstoppable_domains/BUILD.gn b/components/unstoppable_domains/BUILD.gn
new file mode 100644
index 00000000000..dd9e614ee5c
--- /dev/null
+++ b/components/unstoppable_domains/BUILD.gn
@@ -0,0 +1,23 @@
+source_set("constants") {
+ sources = [
+ "constants.cc",
+ "constants.h",
+ ]
+}
+
+source_set("unstoppable_domains") {
+ sources = [
+ "pref_names.cc",
+ "pref_names.h",
+ "unstoppable_domains_service.cc",
+ "unstoppable_domains_service.h",
+ "unstoppable_domains_service_delegate.h",
+ ]
+
+ public_deps = [ ":constants" ]
+
+ deps = [
+ "//components/keyed_service/core",
+ "//components/prefs",
+ ]
+}
diff --git a/components/unstoppable_domains/buildflags/BUILD.gn b/components/unstoppable_domains/buildflags/BUILD.gn
new file mode 100644
index 00000000000..9df0a982d31
--- /dev/null
+++ b/components/unstoppable_domains/buildflags/BUILD.gn
@@ -0,0 +1,7 @@
+import("//brave/components/unstoppable_domains/buildflags/buildflags.gni")
+import("//build/buildflag_header.gni")
+
+buildflag_header("buildflags") {
+ header = "buildflags.h"
+ flags = [ "UNSTOPPABLE_DOMAINS_ENABLED=$unstoppable_domains_enabled" ]
+}
diff --git a/components/unstoppable_domains/buildflags/buildflags.gni b/components/unstoppable_domains/buildflags/buildflags.gni
new file mode 100644
index 00000000000..dda7786ea2e
--- /dev/null
+++ b/components/unstoppable_domains/buildflags/buildflags.gni
@@ -0,0 +1,5 @@
+import("//build/config/features.gni")
+
+declare_args() {
+ unstoppable_domains_enabled = is_mac || is_linux || is_win
+}
diff --git a/components/unstoppable_domains/constants.cc b/components/unstoppable_domains/constants.cc
new file mode 100644
index 00000000000..a826878b5f5
--- /dev/null
+++ b/components/unstoppable_domains/constants.cc
@@ -0,0 +1,14 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "brave/components/unstoppable_domains/constants.h"
+
+namespace unstoppable_domains {
+
+const char kCryptoDomain[] = ".crypto";
+const char kDoHResolver[] =
+ "https://resolver.unstoppable.io/dns-query{?brave_UD}";
+
+} // namespace unstoppable_domains
diff --git a/components/unstoppable_domains/constants.h b/components/unstoppable_domains/constants.h
new file mode 100644
index 00000000000..5f6042d1a5e
--- /dev/null
+++ b/components/unstoppable_domains/constants.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_CONSTANTS_H_
+#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_CONSTANTS_H_
+
+namespace unstoppable_domains {
+
+extern const char kCryptoDomain[];
+extern const char kDoHResolver[];
+
+enum class ResolveMethodTypes {
+ ASK,
+ DISABLED,
+ DNS_OVER_HTTPS,
+};
+
+} // namespace unstoppable_domains
+
+#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_CONSTANTS_H_
diff --git a/components/unstoppable_domains/pref_names.cc b/components/unstoppable_domains/pref_names.cc
new file mode 100644
index 00000000000..cfe58f0a36d
--- /dev/null
+++ b/components/unstoppable_domains/pref_names.cc
@@ -0,0 +1,16 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "brave/components/unstoppable_domains/pref_names.h"
+
+namespace unstoppable_domains {
+
+// Used to determine which method should be used to resolve unstoppable
+// domains, between:
+// Disabled: Disable all unstoppable domains resolution.
+// DNS Over HTTPS: Resolve domain name using a public DNS over HTTPS server.
+const char kResolveMethod[] = "brave.unstoppable_domains.resolve_method";
+
+} // namespace unstoppable_domains
diff --git a/components/unstoppable_domains/pref_names.h b/components/unstoppable_domains/pref_names.h
new file mode 100644
index 00000000000..31b1265805a
--- /dev/null
+++ b/components/unstoppable_domains/pref_names.h
@@ -0,0 +1,15 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_PREF_NAMES_H_
+#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_PREF_NAMES_H_
+
+namespace unstoppable_domains {
+
+extern const char kResolveMethod[];
+
+} // namespace unstoppable_domains
+
+#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_PREF_NAMES_H_
diff --git a/components/unstoppable_domains/unstoppable_domains_service.cc b/components/unstoppable_domains/unstoppable_domains_service.cc
new file mode 100644
index 00000000000..06e80ba4a1f
--- /dev/null
+++ b/components/unstoppable_domains/unstoppable_domains_service.cc
@@ -0,0 +1,45 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "brave/components/unstoppable_domains/unstoppable_domains_service.h"
+
+#include
+
+#include "brave/components/unstoppable_domains/constants.h"
+#include "brave/components/unstoppable_domains/pref_names.h"
+#include "brave/components/unstoppable_domains/unstoppable_domains_service_delegate.h"
+#include "components/prefs/pref_change_registrar.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+
+namespace unstoppable_domains {
+
+UnstoppableDomainsService::UnstoppableDomainsService(
+ std::unique_ptr delegate,
+ content::BrowserContext* context,
+ PrefService* local_state)
+ : local_state_(local_state), delegate_(std::move(delegate)) {
+ pref_change_registrar_ = std::make_unique();
+ pref_change_registrar_->Init(local_state_);
+ pref_change_registrar_->Add(
+ kResolveMethod,
+ base::Bind(&UnstoppableDomainsService::OnPreferenceChanged,
+ base::Unretained(this)));
+}
+
+UnstoppableDomainsService::~UnstoppableDomainsService() = default;
+
+// static
+void UnstoppableDomainsService::RegisterLocalStatePrefs(
+ PrefRegistrySimple* registry) {
+ registry->RegisterIntegerPref(kResolveMethod,
+ static_cast(ResolveMethodTypes::ASK));
+}
+
+void UnstoppableDomainsService::OnPreferenceChanged() {
+ delegate_->UpdateNetworkService();
+}
+
+} // namespace unstoppable_domains
diff --git a/components/unstoppable_domains/unstoppable_domains_service.h b/components/unstoppable_domains/unstoppable_domains_service.h
new file mode 100644
index 00000000000..e07d0ac086f
--- /dev/null
+++ b/components/unstoppable_domains/unstoppable_domains_service.h
@@ -0,0 +1,49 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_H_
+#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_H_
+
+#include
+
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace content {
+class BrowserContext;
+} // namespace content
+
+class PrefChangeRegistrar;
+class PrefRegistrySimple;
+class PrefService;
+
+namespace unstoppable_domains {
+
+class UnstoppableDomainsServiceDelegate;
+
+class UnstoppableDomainsService : public KeyedService {
+ public:
+ UnstoppableDomainsService(
+ std::unique_ptr delegate,
+ content::BrowserContext* context,
+ PrefService* local_state);
+ ~UnstoppableDomainsService() override;
+
+ UnstoppableDomainsService(const UnstoppableDomainsService&) = delete;
+ UnstoppableDomainsService& operator=(const UnstoppableDomainsService&) =
+ delete;
+
+ static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
+
+ private:
+ void OnPreferenceChanged();
+
+ PrefService* local_state_;
+ std::unique_ptr pref_change_registrar_;
+ std::unique_ptr delegate_;
+};
+
+} // namespace unstoppable_domains
+
+#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_H_
diff --git a/components/unstoppable_domains/unstoppable_domains_service_delegate.h b/components/unstoppable_domains/unstoppable_domains_service_delegate.h
new file mode 100644
index 00000000000..91f2726ffb9
--- /dev/null
+++ b/components/unstoppable_domains/unstoppable_domains_service_delegate.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2021 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_H_
+#define BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_H_
+
+namespace unstoppable_domains {
+
+class UnstoppableDomainsServiceDelegate {
+ public:
+ UnstoppableDomainsServiceDelegate() = default;
+ virtual ~UnstoppableDomainsServiceDelegate() = default;
+ virtual void UpdateNetworkService() = 0;
+};
+
+} // namespace unstoppable_domains
+
+#endif // BRAVE_COMPONENTS_UNSTOPPABLE_DOMAINS_UNSTOPPABLE_DOMAINS_SERVICE_DELEGATE_H_
diff --git a/net/sources.gni b/net/sources.gni
index 784143f6efc..d027ca3edb3 100644
--- a/net/sources.gni
+++ b/net/sources.gni
@@ -7,3 +7,8 @@ brave_net_sources = [
"//brave/net/proxy_resolution/proxy_config_service_tor.cc",
"//brave/net/proxy_resolution/proxy_config_service_tor.h",
]
+
+brave_net_deps = [
+ "//brave/components/unstoppable_domains:constants",
+ "//brave/components/unstoppable_domains/buildflags",
+]
diff --git a/patches/chrome-browser-net-stub_resolver_config_reader.cc.patch b/patches/chrome-browser-net-stub_resolver_config_reader.cc.patch
new file mode 100644
index 00000000000..5310997be15
--- /dev/null
+++ b/patches/chrome-browser-net-stub_resolver_config_reader.cc.patch
@@ -0,0 +1,12 @@
+diff --git a/chrome/browser/net/stub_resolver_config_reader.cc b/chrome/browser/net/stub_resolver_config_reader.cc
+index 677f6c50fc602a1c5ba6ca52f4ea6496d7d60e7f..d736b6e06fcbee8fb17e3397cee86f3dbe09ad8e 100644
+--- a/chrome/browser/net/stub_resolver_config_reader.cc
++++ b/chrome/browser/net/stub_resolver_config_reader.cc
+@@ -353,6 +353,7 @@ SecureDnsConfig StubResolverConfigReader::GetAndUpdateConfiguration(
+
+ std::string doh_templates =
+ local_state_->GetString(prefs::kDnsOverHttpsTemplates);
++ BRAVE_GET_AND_UPDATE_CONFIGURATION
+ std::string server_method;
+ std::vector dns_over_https_servers;
+ base::Optional>
diff --git a/patches/chrome-browser-ui-webui-settings-settings_secure_dns_handler.cc.patch b/patches/chrome-browser-ui-webui-settings-settings_secure_dns_handler.cc.patch
new file mode 100644
index 00000000000..cec34e0b85f
--- /dev/null
+++ b/patches/chrome-browser-ui-webui-settings-settings_secure_dns_handler.cc.patch
@@ -0,0 +1,13 @@
+diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
+index 36ddfefcbc527e43d7efcb2210614b9df8c9919f..399f34639a082ea071801de7bc89ebbff275d652 100644
+--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
++++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
+@@ -33,7 +33,7 @@ namespace settings {
+
+ namespace {
+
+-std::unique_ptr CreateSecureDnsSettingDict() {
++std::unique_ptr CreateSecureDnsSettingDict_ChromiumImpl() {
+ // Fetch the current host resolver configuration. It is not sufficient to read
+ // the secure DNS prefs directly since the host resolver configuration takes
+ // other factors into account such as whether a managed environment or
diff --git a/patches/net-BUILD.gn.patch b/patches/net-BUILD.gn.patch
index da3168afa28..fd17d3048e6 100644
--- a/patches/net-BUILD.gn.patch
+++ b/patches/net-BUILD.gn.patch
@@ -1,5 +1,5 @@
diff --git a/net/BUILD.gn b/net/BUILD.gn
-index d214ac4959ff76dd8e95d327c9839ee967d14444..292ce4d3c2c294be04cc8d7ba8ed5ac06e2d58f4 100644
+index d214ac4959ff76dd8e95d327c9839ee967d14444..709ca7acfa482e5d85f2e4207bbbe2d93dd61fee 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1176,6 +1176,7 @@ component("net") {
@@ -10,3 +10,11 @@ index d214ac4959ff76dd8e95d327c9839ee967d14444..292ce4d3c2c294be04cc8d7ba8ed5ac0
if (is_android) {
sources += [
+@@ -1695,6 +1696,7 @@ source_set("net_deps") {
+ ]
+
+ public_configs = net_configs
++ public_deps += brave_net_deps
+
+ if (!is_nacl) {
+ public_deps += [
diff --git a/patches/net-dns-dns_transaction.cc.patch b/patches/net-dns-dns_transaction.cc.patch
new file mode 100644
index 00000000000..db1e6f6f25a
--- /dev/null
+++ b/patches/net-dns-dns_transaction.cc.patch
@@ -0,0 +1,12 @@
+diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
+index 9bfd4cace384ca502716efa191eaa6ccfd6a54a8..9123e8cb94b566ef1a25cbc498dfc859e4165e73 100644
+--- a/net/dns/dns_transaction.cc
++++ b/net/dns/dns_transaction.cc
+@@ -1299,6 +1299,7 @@ class DnsTransactionImpl : public DnsTransaction,
+ DCHECK(secure_);
+
+ size_t doh_server_index = dns_server_iterator_->GetNextAttemptIndex();
++ BRAVE_MAKE_HTTP_ATTEMPT
+
+ unsigned attempt_number = attempts_.size();
+ ConstructDnsHTTPAttempt(