2018-02-01 12:20:49 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* 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/. */
|
|
|
|
|
2020-05-11 11:20:34 +03:00
|
|
|
#include "nsCharSeparatedTokenizer.h"
|
|
|
|
#include "nsComponentManagerUtils.h"
|
2020-12-10 14:09:01 +03:00
|
|
|
#include "nsDirectoryServiceUtils.h"
|
2021-11-29 18:19:15 +03:00
|
|
|
#include "nsHttpConnectionInfo.h"
|
2018-02-01 12:20:49 +03:00
|
|
|
#include "nsICaptivePortalService.h"
|
2020-12-10 14:09:01 +03:00
|
|
|
#include "nsIFile.h"
|
2019-08-24 00:17:15 +03:00
|
|
|
#include "nsIParentalControlsService.h"
|
2019-10-15 16:24:49 +03:00
|
|
|
#include "nsINetworkLinkService.h"
|
2018-02-01 12:20:49 +03:00
|
|
|
#include "nsIObserverService.h"
|
2020-05-18 23:18:08 +03:00
|
|
|
#include "nsIOService.h"
|
2018-02-01 12:20:49 +03:00
|
|
|
#include "nsNetUtil.h"
|
|
|
|
#include "nsStandardURL.h"
|
|
|
|
#include "TRR.h"
|
|
|
|
#include "TRRService.h"
|
|
|
|
|
|
|
|
#include "mozilla/Preferences.h"
|
2019-08-26 22:52:20 +03:00
|
|
|
#include "mozilla/StaticPrefs_network.h"
|
2020-05-11 11:20:34 +03:00
|
|
|
#include "mozilla/Telemetry.h"
|
2021-03-19 11:29:14 +03:00
|
|
|
#include "mozilla/TelemetryComms.h"
|
2018-09-03 17:21:08 +03:00
|
|
|
#include "mozilla/Tokenizer.h"
|
2022-11-01 22:57:45 +03:00
|
|
|
#include "mozilla/dom/ContentParent.h"
|
|
|
|
#include "mozilla/net/NeckoParent.h"
|
2021-11-29 18:19:15 +03:00
|
|
|
#include "mozilla/net/TRRServiceChild.h"
|
2021-06-16 11:14:10 +03:00
|
|
|
// Put DNSLogging.h at the end to avoid LOG being overwritten by other headers.
|
|
|
|
#include "DNSLogging.h"
|
2020-10-01 10:01:58 +03:00
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
static const char kOpenCaptivePortalLoginEvent[] = "captive-portal-login";
|
|
|
|
static const char kClearPrivateData[] = "clear-private-data";
|
|
|
|
static const char kPurge[] = "browser:purge-session-history";
|
2018-03-12 15:19:22 +03:00
|
|
|
static const char kDisableIpv6Pref[] = "network.dns.disableIPv6";
|
2018-02-01 12:20:49 +03:00
|
|
|
|
|
|
|
#define TRR_PREF_PREFIX "network.trr."
|
|
|
|
#define TRR_PREF(x) TRR_PREF_PREFIX x
|
|
|
|
|
2022-01-25 18:57:03 +03:00
|
|
|
namespace mozilla::net {
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2020-03-04 19:11:16 +03:00
|
|
|
StaticRefPtr<nsIThread> sTRRBackgroundThread;
|
2020-10-01 10:01:58 +03:00
|
|
|
static Atomic<TRRService*> sTRRServicePtr;
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2021-02-22 16:51:44 +03:00
|
|
|
static Atomic<size_t, Relaxed> sDomainIndex(0);
|
2023-04-26 12:16:41 +03:00
|
|
|
static Atomic<size_t, Relaxed> sCurrentTRRModeIndex(0);
|
2021-02-22 16:51:44 +03:00
|
|
|
|
2023-04-26 12:16:41 +03:00
|
|
|
constexpr nsLiteralCString kTRRDomains[3][7] = {
|
2021-02-22 16:51:44 +03:00
|
|
|
// clang-format off
|
2023-04-26 12:16:41 +03:00
|
|
|
{
|
|
|
|
// When mode is 0, the provider key has no postfix.
|
2021-02-22 16:51:44 +03:00
|
|
|
"(other)"_ns,
|
|
|
|
"mozilla.cloudflare-dns.com"_ns,
|
|
|
|
"firefox.dns.nextdns.io"_ns,
|
2021-10-06 18:53:48 +03:00
|
|
|
"private.canadianshield.cira.ca"_ns,
|
2021-02-22 16:51:44 +03:00
|
|
|
"doh.xfinity.com"_ns, // Steered clients
|
2022-02-02 00:08:03 +03:00
|
|
|
"dns.shaw.ca"_ns, // Steered clients
|
2023-03-06 12:25:42 +03:00
|
|
|
"dooh.cloudflare-dns.com"_ns, // DNS over Oblivious HTTP
|
2023-04-26 12:16:41 +03:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"(other)_2"_ns,
|
|
|
|
"mozilla.cloudflare-dns.com_2"_ns,
|
|
|
|
"firefox.dns.nextdns.io_2"_ns,
|
|
|
|
"private.canadianshield.cira.ca_2"_ns,
|
|
|
|
"doh.xfinity.com_2"_ns, // Steered clients
|
|
|
|
"dns.shaw.ca_2"_ns, // Steered clients
|
|
|
|
"dooh.cloudflare-dns.com_2"_ns, // DNS over Oblivious HTTP
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"(other)_3"_ns,
|
|
|
|
"mozilla.cloudflare-dns.com_3"_ns,
|
|
|
|
"firefox.dns.nextdns.io_3"_ns,
|
|
|
|
"private.canadianshield.cira.ca_3"_ns,
|
|
|
|
"doh.xfinity.com_3"_ns, // Steered clients
|
|
|
|
"dns.shaw.ca_3"_ns, // Steered clients
|
|
|
|
"dooh.cloudflare-dns.com_3"_ns, // DNS over Oblivious HTTP
|
|
|
|
},
|
2021-02-22 16:51:44 +03:00
|
|
|
// clang-format on
|
|
|
|
};
|
2023-04-26 12:16:41 +03:00
|
|
|
|
|
|
|
// static
|
|
|
|
void TRRService::SetCurrentTRRMode(nsIDNSService::ResolverMode aMode) {
|
|
|
|
// A table to map ResolverMode to the row of kTRRDomains.
|
|
|
|
// When the aMode is 2, we use kTRRDomains[1] as provider keys. When aMode is
|
|
|
|
// 3, we use kTRRDomains[2]. Otherwise, we kTRRDomains[0] is used.
|
|
|
|
static const uint32_t index[] = {0, 0, 1, 2, 0, 0};
|
|
|
|
if (aMode > nsIDNSService::MODE_TRROFF) {
|
|
|
|
aMode = nsIDNSService::MODE_TRROFF;
|
|
|
|
}
|
|
|
|
sCurrentTRRModeIndex = index[static_cast<size_t>(aMode)];
|
|
|
|
}
|
|
|
|
|
2022-12-23 12:26:16 +03:00
|
|
|
// static
|
|
|
|
void TRRService::SetProviderDomain(const nsACString& aTRRDomain) {
|
|
|
|
sDomainIndex = 0;
|
2023-04-26 12:16:41 +03:00
|
|
|
for (size_t i = 1; i < std::size(kTRRDomains[0]); i++) {
|
|
|
|
if (aTRRDomain.Equals(kTRRDomains[0][i])) {
|
2022-12-23 12:26:16 +03:00
|
|
|
sDomainIndex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-02-22 16:51:44 +03:00
|
|
|
|
|
|
|
// static
|
2023-04-26 12:16:41 +03:00
|
|
|
const nsCString& TRRService::ProviderKey() {
|
|
|
|
return kTRRDomains[sCurrentTRRModeIndex][sDomainIndex];
|
|
|
|
}
|
2021-02-22 16:51:44 +03:00
|
|
|
|
2021-11-29 18:19:15 +03:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED(TRRService, TRRServiceBase, nsIObserver,
|
|
|
|
nsISupportsWeakReference)
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2021-05-03 12:09:17 +03:00
|
|
|
NS_IMPL_ADDREF_USING_AGGREGATOR(TRRService::ConfirmationContext, OwningObject())
|
|
|
|
NS_IMPL_RELEASE_USING_AGGREGATOR(TRRService::ConfirmationContext,
|
|
|
|
OwningObject())
|
2021-09-07 11:01:18 +03:00
|
|
|
NS_IMPL_QUERY_INTERFACE(TRRService::ConfirmationContext, nsITimerCallback,
|
|
|
|
nsINamed)
|
2021-05-03 12:09:17 +03:00
|
|
|
|
2022-05-13 00:55:01 +03:00
|
|
|
TRRService::TRRService() : mLock("TRRService", this) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
|
|
}
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2021-07-26 12:37:37 +03:00
|
|
|
// static
|
|
|
|
TRRService* TRRService::Get() { return sTRRServicePtr; }
|
|
|
|
|
2020-05-18 23:18:03 +03:00
|
|
|
// static
|
2020-06-23 14:11:16 +03:00
|
|
|
void TRRService::AddObserver(nsIObserver* aObserver,
|
|
|
|
nsIObserverService* aObserverService) {
|
|
|
|
nsCOMPtr<nsIObserverService> observerService;
|
|
|
|
if (aObserverService) {
|
|
|
|
observerService = aObserverService;
|
|
|
|
} else {
|
|
|
|
observerService = mozilla::services::GetObserverService();
|
|
|
|
}
|
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
if (observerService) {
|
2020-05-18 23:18:03 +03:00
|
|
|
observerService->AddObserver(aObserver, NS_CAPTIVE_PORTAL_CONNECTIVITY,
|
|
|
|
true);
|
|
|
|
observerService->AddObserver(aObserver, kOpenCaptivePortalLoginEvent, true);
|
|
|
|
observerService->AddObserver(aObserver, kClearPrivateData, true);
|
|
|
|
observerService->AddObserver(aObserver, kPurge, true);
|
|
|
|
observerService->AddObserver(aObserver, NS_NETWORK_LINK_TOPIC, true);
|
|
|
|
observerService->AddObserver(aObserver, NS_DNS_SUFFIX_LIST_UPDATED_TOPIC,
|
|
|
|
true);
|
|
|
|
observerService->AddObserver(aObserver, "xpcom-shutdown-threads", true);
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
2020-05-18 23:18:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
bool TRRService::CheckCaptivePortalIsPassed() {
|
|
|
|
bool result = false;
|
2018-03-12 16:48:49 +03:00
|
|
|
nsCOMPtr<nsICaptivePortalService> captivePortalService =
|
|
|
|
do_GetService(NS_CAPTIVEPORTAL_CID);
|
|
|
|
if (captivePortalService) {
|
|
|
|
int32_t captiveState;
|
|
|
|
MOZ_ALWAYS_SUCCEEDS(captivePortalService->GetState(&captiveState));
|
|
|
|
|
|
|
|
if ((captiveState == nsICaptivePortalService::UNLOCKED_PORTAL) ||
|
|
|
|
(captiveState == nsICaptivePortalService::NOT_CAPTIVE)) {
|
2020-05-18 23:18:03 +03:00
|
|
|
result = true;
|
2018-03-12 16:48:49 +03:00
|
|
|
}
|
|
|
|
LOG(("TRRService::Init mCaptiveState=%d mCaptiveIsPassed=%d\n",
|
2020-05-18 23:18:03 +03:00
|
|
|
captiveState, (int)result));
|
2018-03-12 16:48:49 +03:00
|
|
|
}
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2020-05-18 23:18:03 +03:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-02-25 15:52:28 +03:00
|
|
|
static void EventTelemetryPrefChanged(const char* aPref, void* aData) {
|
|
|
|
Telemetry::SetEventRecordingEnabled(
|
|
|
|
"network.dns"_ns,
|
|
|
|
StaticPrefs::network_trr_confirmation_telemetry_enabled());
|
|
|
|
}
|
|
|
|
|
2020-05-18 23:18:03 +03:00
|
|
|
nsresult TRRService::Init() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
|
|
if (mInitialized) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
mInitialized = true;
|
|
|
|
|
|
|
|
AddObserver(this);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrefBranch> prefBranch;
|
|
|
|
GetPrefBranch(getter_AddRefs(prefBranch));
|
|
|
|
if (prefBranch) {
|
|
|
|
prefBranch->AddObserver(TRR_PREF_PREFIX, this, true);
|
|
|
|
prefBranch->AddObserver(kDisableIpv6Pref, this, true);
|
|
|
|
prefBranch->AddObserver(kRolloutURIPref, this, true);
|
|
|
|
prefBranch->AddObserver(kRolloutModePref, this, true);
|
|
|
|
}
|
2019-08-24 00:17:15 +03:00
|
|
|
|
2020-10-01 10:01:58 +03:00
|
|
|
sTRRServicePtr = this;
|
|
|
|
|
|
|
|
ReadPrefs(nullptr);
|
2021-05-03 12:09:18 +03:00
|
|
|
mConfirmation.HandleEvent(ConfirmationEvent::Init);
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2020-05-18 23:18:03 +03:00
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
mCaptiveIsPassed = CheckCaptivePortalIsPassed();
|
2020-03-04 19:11:16 +03:00
|
|
|
|
2020-05-18 23:18:03 +03:00
|
|
|
mParentalControlEnabled = GetParentalControlEnabledInternal();
|
|
|
|
|
2021-02-17 13:26:41 +03:00
|
|
|
mLinkService = do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID);
|
|
|
|
if (mLinkService) {
|
2020-05-18 23:18:03 +03:00
|
|
|
nsTArray<nsCString> suffixList;
|
2021-02-17 13:26:41 +03:00
|
|
|
mLinkService->GetDnsSuffixList(suffixList);
|
2020-05-18 23:18:03 +03:00
|
|
|
RebuildSuffixList(std::move(suffixList));
|
|
|
|
}
|
2020-03-04 19:11:16 +03:00
|
|
|
|
2020-05-18 23:18:03 +03:00
|
|
|
nsCOMPtr<nsIThread> thread;
|
|
|
|
if (NS_FAILED(
|
|
|
|
NS_NewNamedThread("TRR Background", getter_AddRefs(thread)))) {
|
|
|
|
NS_WARNING("NS_NewNamedThread failed!");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
sTRRBackgroundThread = thread;
|
|
|
|
}
|
2020-03-08 16:52:07 +03:00
|
|
|
|
2021-01-26 17:19:09 +03:00
|
|
|
mODoHService = new ODoHService();
|
|
|
|
if (!mODoHService->Init()) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2021-02-25 15:52:28 +03:00
|
|
|
Preferences::RegisterCallbackAndCall(
|
|
|
|
EventTelemetryPrefChanged,
|
|
|
|
"network.trr.confirmation_telemetry_enabled"_ns);
|
2021-02-17 13:26:41 +03:00
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
LOG(("Initialized TRRService\n"));
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2020-05-18 23:18:03 +03:00
|
|
|
// static
|
|
|
|
bool TRRService::GetParentalControlEnabledInternal() {
|
2019-08-24 00:17:15 +03:00
|
|
|
nsCOMPtr<nsIParentalControlsService> pc =
|
|
|
|
do_CreateInstance("@mozilla.org/parental-controls-service;1");
|
|
|
|
if (pc) {
|
2020-05-18 23:18:03 +03:00
|
|
|
bool result = false;
|
|
|
|
pc->GetParentalControlsEnabled(&result);
|
|
|
|
LOG(("TRRService::GetParentalControlEnabledInternal=%d\n", result));
|
|
|
|
return result;
|
2019-08-24 00:17:15 +03:00
|
|
|
}
|
2020-05-18 23:18:03 +03:00
|
|
|
|
|
|
|
return false;
|
2019-08-24 00:17:15 +03:00
|
|
|
}
|
|
|
|
|
2020-04-27 20:18:08 +03:00
|
|
|
void TRRService::SetDetectedTrrURI(const nsACString& aURI) {
|
2021-04-07 10:30:00 +03:00
|
|
|
LOG(("SetDetectedTrrURI(%s", nsPromiseFlatCString(aURI).get()));
|
2020-04-27 20:19:46 +03:00
|
|
|
// If the user has set a custom URI then we don't want to override that.
|
2021-09-30 14:58:52 +03:00
|
|
|
// If the URI is set via doh-rollout.uri, mURIPref will be empty
|
2021-04-07 10:30:00 +03:00
|
|
|
// (see TRRServiceBase::OnTRRURIChange)
|
2021-09-30 14:58:52 +03:00
|
|
|
if (!mURIPref.IsEmpty()) {
|
2021-04-07 10:30:00 +03:00
|
|
|
LOG(("Already has user value. Not setting URI"));
|
2020-04-27 20:19:46 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-03-21 17:51:48 +03:00
|
|
|
if (StaticPrefs::network_trr_use_ohttp()) {
|
|
|
|
LOG(("No autodetection when using OHTTP"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-24 22:43:51 +03:00
|
|
|
mURISetByDetection = MaybeSetPrivateURI(aURI);
|
2020-04-27 20:18:08 +03:00
|
|
|
}
|
|
|
|
|
2021-02-04 20:34:27 +03:00
|
|
|
bool TRRService::Enabled(nsIRequest::TRRMode aRequestMode) {
|
|
|
|
if (mMode == nsIDNSService::MODE_TRROFF ||
|
|
|
|
aRequestMode == nsIRequest::TRR_DISABLED_MODE) {
|
2021-03-19 20:51:26 +03:00
|
|
|
LOG(("TRR service not enabled - off or disabled"));
|
2020-01-07 23:20:38 +03:00
|
|
|
return false;
|
|
|
|
}
|
2021-02-04 20:34:27 +03:00
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
// If already confirmed, service is enabled.
|
|
|
|
if (mConfirmation.State() == CONFIRM_OK ||
|
|
|
|
aRequestMode == nsIRequest::TRR_ONLY_MODE) {
|
|
|
|
LOG(("TRR service enabled - confirmed or trr_only request"));
|
|
|
|
return true;
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
// If this is a TRR_FIRST request but the resolver has a different mode,
|
|
|
|
// just go ahead and let it try to use TRR.
|
|
|
|
if (aRequestMode == nsIRequest::TRR_FIRST_MODE &&
|
|
|
|
mMode != nsIDNSService::MODE_TRRFIRST) {
|
|
|
|
LOG(("TRR service enabled - trr_first request"));
|
|
|
|
return true;
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
// In TRR_ONLY_MODE / confirmationNS == "skip" we don't try to confirm.
|
|
|
|
if (mConfirmation.State() == CONFIRM_DISABLED) {
|
|
|
|
LOG(("TRRService service enabled - confirmation is disabled"));
|
2021-02-04 20:34:27 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
LOG(("TRRService::Enabled mConfirmation.mState=%d mCaptiveIsPassed=%d\n",
|
|
|
|
mConfirmation.State(), (int)mCaptiveIsPassed));
|
2018-03-09 11:05:48 +03:00
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
if (StaticPrefs::network_trr_wait_for_confirmation()) {
|
|
|
|
return mConfirmation.State() == CONFIRM_OK;
|
2021-02-04 20:34:27 +03:00
|
|
|
}
|
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
if (StaticPrefs::network_trr_attempt_when_retrying_confirmation()) {
|
|
|
|
return mConfirmation.State() == CONFIRM_OK ||
|
|
|
|
mConfirmation.State() == CONFIRM_TRYING_OK ||
|
|
|
|
mConfirmation.State() == CONFIRM_TRYING_FAILED;
|
2021-02-04 20:34:27 +03:00
|
|
|
}
|
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
return mConfirmation.State() == CONFIRM_OK ||
|
|
|
|
mConfirmation.State() == CONFIRM_TRYING_OK;
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TRRService::GetPrefBranch(nsIPrefBranch** result) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
|
|
*result = nullptr;
|
|
|
|
CallGetService(NS_PREFSERVICE_CONTRACTID, result);
|
|
|
|
}
|
|
|
|
|
2020-04-24 22:43:51 +03:00
|
|
|
bool TRRService::MaybeSetPrivateURI(const nsACString& aURI) {
|
|
|
|
bool clearCache = false;
|
|
|
|
nsAutoCString newURI(aURI);
|
2021-04-07 10:30:00 +03:00
|
|
|
LOG(("MaybeSetPrivateURI(%s)", newURI.get()));
|
2021-04-06 21:49:20 +03:00
|
|
|
|
2021-04-07 10:30:00 +03:00
|
|
|
ProcessURITemplate(newURI);
|
2020-04-24 22:43:51 +03:00
|
|
|
{
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2020-04-24 22:43:51 +03:00
|
|
|
if (mPrivateURI.Equals(newURI)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mPrivateURI.IsEmpty()) {
|
2020-07-11 22:32:27 +03:00
|
|
|
LOG(("TRRService clearing blocklist because of change in uri service\n"));
|
2020-07-11 22:32:45 +03:00
|
|
|
auto bl = mTRRBLStorage.Lock();
|
|
|
|
bl->Clear();
|
2020-04-24 22:43:51 +03:00
|
|
|
clearCache = true;
|
|
|
|
}
|
2021-02-22 16:51:44 +03:00
|
|
|
|
2023-04-11 12:57:29 +03:00
|
|
|
nsAutoCString host;
|
|
|
|
|
2021-02-22 16:51:44 +03:00
|
|
|
nsCOMPtr<nsIURI> url;
|
2023-04-11 12:57:29 +03:00
|
|
|
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(url), newURI))) {
|
|
|
|
url->GetHost(host);
|
2021-02-22 16:51:44 +03:00
|
|
|
}
|
|
|
|
|
2022-12-23 12:26:16 +03:00
|
|
|
SetProviderDomain(host);
|
2021-02-22 16:51:44 +03:00
|
|
|
|
2020-04-24 22:43:51 +03:00
|
|
|
mPrivateURI = newURI;
|
2021-03-19 20:51:26 +03:00
|
|
|
|
2022-11-01 22:57:45 +03:00
|
|
|
// Notify the content processes of the new TRR
|
|
|
|
for (auto* cp :
|
|
|
|
dom::ContentParent::AllProcesses(dom::ContentParent::eLive)) {
|
|
|
|
PNeckoParent* neckoParent =
|
|
|
|
SingleManagedOrNull(cp->ManagedPNeckoParent());
|
|
|
|
if (!neckoParent) {
|
|
|
|
continue;
|
|
|
|
}
|
2022-12-23 12:26:16 +03:00
|
|
|
Unused << neckoParent->SendSetTRRDomain(host);
|
2022-11-01 22:57:45 +03:00
|
|
|
}
|
|
|
|
|
2021-11-29 18:19:15 +03:00
|
|
|
AsyncCreateTRRConnectionInfo(mPrivateURI);
|
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
// The URI has changed. We should trigger a new confirmation immediately.
|
|
|
|
// We must do this here because the URI could also change because of
|
|
|
|
// steering.
|
2022-02-21 15:23:19 +03:00
|
|
|
mConfirmationTriggered =
|
|
|
|
mConfirmation.HandleEvent(ConfirmationEvent::URIChange, lock);
|
2020-04-24 22:43:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clear the cache because we changed the URI
|
|
|
|
if (clearCache) {
|
|
|
|
ClearEntireCache();
|
|
|
|
}
|
2020-04-27 20:19:17 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
obs->NotifyObservers(nullptr, NS_NETWORK_TRR_URI_CHANGED_TOPIC, nullptr);
|
|
|
|
}
|
2020-04-24 22:43:51 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
nsresult TRRService::ReadPrefs(const char* name) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
2019-10-14 17:57:38 +03:00
|
|
|
|
|
|
|
// Whenever a pref change occurs that would cause us to clear the cache
|
|
|
|
// we set this to true then do it at the end of the method.
|
|
|
|
bool clearEntireCache = false;
|
|
|
|
|
2020-05-13 16:37:02 +03:00
|
|
|
if (!name || !strcmp(name, TRR_PREF("mode")) ||
|
|
|
|
!strcmp(name, kRolloutModePref)) {
|
2021-01-25 15:22:43 +03:00
|
|
|
nsIDNSService::ResolverMode prevMode = Mode();
|
2020-11-27 13:44:28 +03:00
|
|
|
|
2020-05-18 23:18:15 +03:00
|
|
|
OnTRRModeChange();
|
2020-11-27 13:44:28 +03:00
|
|
|
// When the TRR service gets disabled we should purge the TRR cache to
|
|
|
|
// make sure we don't use any of the cached entries on a network where
|
|
|
|
// they are invalid - for example after turning on a VPN.
|
|
|
|
if (TRR_DISABLED(Mode()) && !TRR_DISABLED(prevMode)) {
|
|
|
|
clearEntireCache = true;
|
|
|
|
}
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
2020-04-27 20:16:07 +03:00
|
|
|
if (!name || !strcmp(name, TRR_PREF("uri")) ||
|
2021-06-24 02:28:16 +03:00
|
|
|
!strcmp(name, TRR_PREF("default_provider_uri")) ||
|
2023-03-28 11:11:28 +03:00
|
|
|
!strcmp(name, kRolloutURIPref) || !strcmp(name, TRR_PREF("ohttp.uri")) ||
|
|
|
|
!strcmp(name, TRR_PREF("use_ohttp"))) {
|
2020-05-18 23:18:15 +03:00
|
|
|
OnTRRURIChange();
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
|
|
|
if (!name || !strcmp(name, TRR_PREF("credentials"))) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2018-02-01 12:20:49 +03:00
|
|
|
Preferences::GetCString(TRR_PREF("credentials"), mPrivateCred);
|
|
|
|
}
|
|
|
|
if (!name || !strcmp(name, TRR_PREF("confirmationNS"))) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2018-02-01 12:20:49 +03:00
|
|
|
Preferences::GetCString(TRR_PREF("confirmationNS"), mConfirmationNS);
|
2021-03-19 20:51:26 +03:00
|
|
|
LOG(("confirmationNS = %s", mConfirmationNS.get()));
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
2021-04-12 19:07:06 +03:00
|
|
|
if (!name || !strcmp(name, TRR_PREF("bootstrapAddr"))) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2021-04-12 19:07:06 +03:00
|
|
|
Preferences::GetCString(TRR_PREF("bootstrapAddr"), mBootstrapAddr);
|
2019-10-14 17:57:38 +03:00
|
|
|
clearEntireCache = true;
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
2018-03-12 15:19:22 +03:00
|
|
|
if (!name || !strcmp(name, kDisableIpv6Pref)) {
|
|
|
|
bool tmp;
|
|
|
|
if (NS_SUCCEEDED(Preferences::GetBool(kDisableIpv6Pref, &tmp))) {
|
|
|
|
mDisableIPv6 = tmp;
|
|
|
|
}
|
|
|
|
}
|
2019-08-14 22:35:16 +03:00
|
|
|
if (!name || !strcmp(name, TRR_PREF("excluded-domains")) ||
|
2020-01-07 22:32:32 +03:00
|
|
|
!strcmp(name, TRR_PREF("builtin-excluded-domains"))) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2019-08-23 23:23:12 +03:00
|
|
|
mExcludedDomains.Clear();
|
2019-09-12 15:44:16 +03:00
|
|
|
|
|
|
|
auto parseExcludedDomains = [this](const char* aPrefName) {
|
|
|
|
nsAutoCString excludedDomains;
|
2022-05-13 00:55:01 +03:00
|
|
|
mLock.AssertCurrentThreadOwns();
|
2019-09-12 15:44:16 +03:00
|
|
|
Preferences::GetCString(aPrefName, excludedDomains);
|
|
|
|
if (excludedDomains.IsEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-12-16 22:10:34 +03:00
|
|
|
for (const nsACString& tokenSubstring :
|
|
|
|
nsCCharSeparatedTokenizerTemplate<
|
|
|
|
NS_IsAsciiWhitespace, nsTokenizerFlags::SeparatorOptional>(
|
|
|
|
excludedDomains, ',')
|
|
|
|
.ToRange()) {
|
|
|
|
nsCString token{tokenSubstring};
|
2019-09-12 15:44:16 +03:00
|
|
|
LOG(("TRRService::ReadPrefs %s host:[%s]\n", aPrefName, token.get()));
|
2021-03-23 13:36:35 +03:00
|
|
|
mExcludedDomains.Insert(token);
|
2019-09-12 15:44:16 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
parseExcludedDomains(TRR_PREF("excluded-domains"));
|
|
|
|
parseExcludedDomains(TRR_PREF("builtin-excluded-domains"));
|
2019-10-14 17:57:38 +03:00
|
|
|
clearEntireCache = true;
|
2019-11-10 20:11:41 +03:00
|
|
|
}
|
|
|
|
|
2019-10-14 17:57:38 +03:00
|
|
|
// if name is null, then we're just now initializing. In that case we don't
|
|
|
|
// need to clear the cache.
|
|
|
|
if (name && clearEntireCache) {
|
2020-04-27 20:20:18 +03:00
|
|
|
ClearEntireCache();
|
2019-10-14 17:57:38 +03:00
|
|
|
}
|
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2020-04-27 20:20:18 +03:00
|
|
|
void TRRService::ClearEntireCache() {
|
2020-08-31 15:49:59 +03:00
|
|
|
if (!StaticPrefs::network_trr_clear_cache_on_pref_change()) {
|
2020-04-27 20:20:18 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
|
|
|
|
if (!dns) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dns->ClearCache(true);
|
|
|
|
}
|
|
|
|
|
2020-10-01 10:01:58 +03:00
|
|
|
void TRRService::AddEtcHosts(const nsTArray<nsCString>& aArray) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2020-10-01 10:01:58 +03:00
|
|
|
for (const auto& item : aArray) {
|
|
|
|
LOG(("Adding %s from /etc/hosts to excluded domains", item.get()));
|
2021-03-23 13:36:35 +03:00
|
|
|
mEtcHostsDomains.Insert(item);
|
2020-10-01 10:01:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TRRService::ReadEtcHostsFile() {
|
2022-01-06 06:48:57 +03:00
|
|
|
if (!XRE_IsParentProcess()) {
|
2020-10-01 10:01:58 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-06 06:48:57 +03:00
|
|
|
DoReadEtcHostsFile([](const nsTArray<nsCString>* aArray) -> bool {
|
|
|
|
RefPtr<TRRService> service(sTRRServicePtr);
|
|
|
|
if (service && aArray) {
|
|
|
|
service->AddEtcHosts(*aArray);
|
2020-10-01 10:01:58 +03:00
|
|
|
}
|
2022-01-06 06:48:57 +03:00
|
|
|
return !!service;
|
|
|
|
});
|
2020-10-01 10:01:58 +03:00
|
|
|
}
|
|
|
|
|
2021-11-29 18:19:15 +03:00
|
|
|
void TRRService::GetURI(nsACString& result) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2018-02-01 12:20:49 +03:00
|
|
|
result = mPrivateURI;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult TRRService::GetCredentials(nsCString& result) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2018-02-01 12:20:49 +03:00
|
|
|
result = mPrivateCred;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2019-08-26 22:52:20 +03:00
|
|
|
uint32_t TRRService::GetRequestTimeout() {
|
2021-01-25 15:22:43 +03:00
|
|
|
if (mMode == nsIDNSService::MODE_TRRONLY) {
|
2019-08-26 22:52:20 +03:00
|
|
|
return StaticPrefs::network_trr_request_timeout_mode_trronly_ms();
|
|
|
|
}
|
|
|
|
|
2022-02-07 12:04:44 +03:00
|
|
|
if (StaticPrefs::network_trr_strict_native_fallback()) {
|
|
|
|
return StaticPrefs::network_trr_strict_fallback_request_timeout_ms();
|
|
|
|
}
|
|
|
|
|
2019-08-26 22:52:20 +03:00
|
|
|
return StaticPrefs::network_trr_request_timeout_ms();
|
|
|
|
}
|
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
nsresult TRRService::Start() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
|
|
if (!mInitialized) {
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
TRRService::~TRRService() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
|
|
LOG(("Exiting TRRService\n"));
|
|
|
|
}
|
|
|
|
|
2020-03-04 19:11:16 +03:00
|
|
|
nsresult TRRService::DispatchTRRRequest(TRR* aTrrRequest) {
|
|
|
|
return DispatchTRRRequestInternal(aTrrRequest, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult TRRService::DispatchTRRRequestInternal(TRR* aTrrRequest,
|
|
|
|
bool aWithLock) {
|
|
|
|
NS_ENSURE_ARG_POINTER(aTrrRequest);
|
|
|
|
|
2021-01-26 17:19:09 +03:00
|
|
|
nsCOMPtr<nsIThread> thread = MainThreadOrTRRThread(aWithLock);
|
2020-03-04 19:11:16 +03:00
|
|
|
if (!thread) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2021-01-26 17:19:09 +03:00
|
|
|
RefPtr<TRR> trr = aTrrRequest;
|
2020-03-04 19:11:16 +03:00
|
|
|
return thread->Dispatch(trr.forget());
|
|
|
|
}
|
|
|
|
|
2021-01-26 17:19:09 +03:00
|
|
|
already_AddRefed<nsIThread> TRRService::MainThreadOrTRRThread(bool aWithLock) {
|
|
|
|
if (!StaticPrefs::network_trr_fetch_off_main_thread() ||
|
2023-05-02 16:00:27 +03:00
|
|
|
XRE_IsSocketProcess() || mDontUseTRRThread) {
|
2021-01-26 17:19:09 +03:00
|
|
|
return do_GetMainThread();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIThread> thread = aWithLock ? TRRThread() : TRRThread_locked();
|
|
|
|
return thread.forget();
|
|
|
|
}
|
|
|
|
|
2020-03-04 19:11:16 +03:00
|
|
|
already_AddRefed<nsIThread> TRRService::TRRThread() {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2020-03-04 19:11:16 +03:00
|
|
|
return TRRThread_locked();
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsIThread> TRRService::TRRThread_locked() {
|
|
|
|
RefPtr<nsIThread> thread = sTRRBackgroundThread;
|
|
|
|
return thread.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TRRService::IsOnTRRThread() {
|
|
|
|
nsCOMPtr<nsIThread> thread;
|
|
|
|
{
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2020-03-04 19:11:16 +03:00
|
|
|
thread = sTRRBackgroundThread;
|
|
|
|
}
|
|
|
|
if (!thread) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return thread->IsOnCurrentThread();
|
|
|
|
}
|
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
TRRService::Observe(nsISupports* aSubject, const char* aTopic,
|
|
|
|
const char16_t* aData) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
|
|
|
LOG(("TRR::Observe() topic=%s\n", aTopic));
|
|
|
|
if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
2022-02-21 15:23:19 +03:00
|
|
|
// Reset the state of whether a confirmation is triggered, so we can check
|
|
|
|
// if we create a new one after ReadPrefs().
|
|
|
|
mConfirmationTriggered = false;
|
2018-02-01 12:20:49 +03:00
|
|
|
ReadPrefs(NS_ConvertUTF16toUTF8(aData).get());
|
2022-04-22 12:39:31 +03:00
|
|
|
{
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2022-04-22 12:39:31 +03:00
|
|
|
mConfirmation.RecordEvent("pref-change", lock);
|
|
|
|
}
|
2021-04-07 10:30:00 +03:00
|
|
|
|
|
|
|
// We should only trigger a new confirmation if reading the prefs didn't
|
|
|
|
// already trigger one.
|
2022-02-21 15:23:19 +03:00
|
|
|
if (!mConfirmationTriggered) {
|
2021-05-03 12:09:18 +03:00
|
|
|
mConfirmation.HandleEvent(ConfirmationEvent::PrefChange);
|
2021-04-07 10:30:00 +03:00
|
|
|
}
|
2018-02-01 12:20:49 +03:00
|
|
|
} else if (!strcmp(aTopic, kOpenCaptivePortalLoginEvent)) {
|
|
|
|
// We are in a captive portal
|
|
|
|
LOG(("TRRservice in captive portal\n"));
|
|
|
|
mCaptiveIsPassed = false;
|
2021-05-03 12:09:19 +03:00
|
|
|
mConfirmation.SetCaptivePortalStatus(
|
|
|
|
nsICaptivePortalService::LOCKED_PORTAL);
|
2018-02-01 12:20:49 +03:00
|
|
|
} else if (!strcmp(aTopic, NS_CAPTIVE_PORTAL_CONNECTIVITY)) {
|
|
|
|
nsAutoCString data = NS_ConvertUTF16toUTF8(aData);
|
|
|
|
LOG(("TRRservice captive portal was %s\n", data.get()));
|
2021-02-17 13:26:41 +03:00
|
|
|
nsCOMPtr<nsICaptivePortalService> cps = do_QueryInterface(aSubject);
|
|
|
|
if (cps) {
|
2021-05-03 12:09:19 +03:00
|
|
|
mConfirmation.SetCaptivePortalStatus(cps->State());
|
2021-04-07 10:30:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we were previously in a captive portal, this event means we will
|
|
|
|
// need to trigger confirmation again. Otherwise it's just a periodical
|
|
|
|
// captive-portal check that completed and we don't need to react to it.
|
|
|
|
if (!mCaptiveIsPassed) {
|
2021-05-03 12:09:18 +03:00
|
|
|
mConfirmation.HandleEvent(ConfirmationEvent::CaptivePortalConnectivity);
|
2021-02-17 13:26:41 +03:00
|
|
|
}
|
2021-04-07 10:30:00 +03:00
|
|
|
|
|
|
|
mCaptiveIsPassed = true;
|
2018-02-01 12:20:49 +03:00
|
|
|
} else if (!strcmp(aTopic, kClearPrivateData) || !strcmp(aTopic, kPurge)) {
|
2020-07-11 22:32:45 +03:00
|
|
|
// flush the TRR blocklist
|
|
|
|
auto bl = mTRRBLStorage.Lock();
|
|
|
|
bl->Clear();
|
2019-12-10 12:37:05 +03:00
|
|
|
} else if (!strcmp(aTopic, NS_DNS_SUFFIX_LIST_UPDATED_TOPIC) ||
|
|
|
|
!strcmp(aTopic, NS_NETWORK_LINK_TOPIC)) {
|
2020-05-18 23:18:03 +03:00
|
|
|
// nsINetworkLinkService is only available on parent process.
|
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
nsCOMPtr<nsINetworkLinkService> link = do_QueryInterface(aSubject);
|
|
|
|
// The network link service notification normally passes itself as the
|
|
|
|
// subject, but some unit tests will sometimes pass a null subject.
|
|
|
|
if (link) {
|
|
|
|
nsTArray<nsCString> suffixList;
|
|
|
|
link->GetDnsSuffixList(suffixList);
|
|
|
|
RebuildSuffixList(std::move(suffixList));
|
|
|
|
}
|
|
|
|
}
|
2020-04-24 22:43:51 +03:00
|
|
|
|
2021-02-17 13:26:41 +03:00
|
|
|
if (!strcmp(aTopic, NS_NETWORK_LINK_TOPIC)) {
|
|
|
|
if (NS_ConvertUTF16toUTF8(aData).EqualsLiteral(
|
|
|
|
NS_NETWORK_LINK_DATA_DOWN)) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2022-04-22 12:39:31 +03:00
|
|
|
mConfirmation.RecordEvent("network-change", lock);
|
2021-02-17 13:26:41 +03:00
|
|
|
}
|
2021-03-19 20:51:26 +03:00
|
|
|
|
2021-02-17 13:26:41 +03:00
|
|
|
if (mURISetByDetection) {
|
|
|
|
// If the URI was set via SetDetectedTrrURI we need to restore it to the
|
|
|
|
// default pref when a network link change occurs.
|
|
|
|
CheckURIPrefs();
|
|
|
|
}
|
2021-03-19 20:51:26 +03:00
|
|
|
|
|
|
|
if (NS_ConvertUTF16toUTF8(aData).EqualsLiteral(NS_NETWORK_LINK_DATA_UP)) {
|
2021-05-03 12:09:18 +03:00
|
|
|
mConfirmation.HandleEvent(ConfirmationEvent::NetworkUp);
|
2021-03-19 20:51:26 +03:00
|
|
|
}
|
2020-04-24 22:43:51 +03:00
|
|
|
}
|
2020-03-04 19:11:16 +03:00
|
|
|
} else if (!strcmp(aTopic, "xpcom-shutdown-threads")) {
|
2022-05-18 16:01:32 +03:00
|
|
|
mShutdown = true;
|
2021-02-17 13:26:41 +03:00
|
|
|
// If a confirmation is still in progress we record the event.
|
|
|
|
// Since there should be no more confirmations after this, the shutdown
|
|
|
|
// reason would not really be recorded in telemetry.
|
2022-05-18 16:01:32 +03:00
|
|
|
{
|
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
|
|
|
mConfirmation.RecordEvent("shutdown", lock);
|
|
|
|
}
|
2021-02-17 13:26:41 +03:00
|
|
|
|
2020-03-04 19:11:16 +03:00
|
|
|
if (sTRRBackgroundThread) {
|
|
|
|
nsCOMPtr<nsIThread> thread;
|
2022-04-22 12:39:31 +03:00
|
|
|
thread = sTRRBackgroundThread.get();
|
|
|
|
sTRRBackgroundThread = nullptr;
|
2020-03-04 19:11:16 +03:00
|
|
|
MOZ_ALWAYS_SUCCEEDS(thread->Shutdown());
|
2020-10-01 10:01:58 +03:00
|
|
|
sTRRServicePtr = nullptr;
|
2020-03-04 19:11:16 +03:00
|
|
|
}
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2020-05-18 23:18:03 +03:00
|
|
|
void TRRService::RebuildSuffixList(nsTArray<nsCString>&& aSuffixList) {
|
2022-05-18 16:01:32 +03:00
|
|
|
if (!StaticPrefs::network_trr_split_horizon_mitigations() || mShutdown) {
|
2020-09-02 12:26:48 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2019-11-24 17:54:02 +03:00
|
|
|
mDNSSuffixDomains.Clear();
|
2020-05-18 23:18:03 +03:00
|
|
|
for (const auto& item : aSuffixList) {
|
2019-11-21 13:02:48 +03:00
|
|
|
LOG(("TRRService adding %s to suffix list", item.get()));
|
2021-03-23 13:36:35 +03:00
|
|
|
mDNSSuffixDomains.Insert(item);
|
2019-11-21 13:02:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-02 16:21:55 +03:00
|
|
|
void TRRService::ConfirmationContext::SetState(
|
|
|
|
enum ConfirmationState aNewState) {
|
|
|
|
mState = aNewState;
|
|
|
|
|
2023-04-11 12:57:27 +03:00
|
|
|
enum ConfirmationState state = mState;
|
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
|
|
|
"TRRService::ConfirmationContextNotify", [state] {
|
2023-03-26 00:23:18 +03:00
|
|
|
if (nsCOMPtr<nsIObserverService> obs =
|
|
|
|
mozilla::services::GetObserverService()) {
|
2023-04-11 12:57:27 +03:00
|
|
|
auto stateString =
|
|
|
|
[](enum ConfirmationState aState) -> const char16_t* {
|
|
|
|
switch (aState) {
|
|
|
|
case CONFIRM_OFF:
|
|
|
|
return u"CONFIRM_OFF";
|
|
|
|
case CONFIRM_TRYING_OK:
|
|
|
|
return u"CONFIRM_TRYING_OK";
|
|
|
|
case CONFIRM_OK:
|
|
|
|
return u"CONFIRM_OK";
|
|
|
|
case CONFIRM_FAILED:
|
|
|
|
return u"CONFIRM_FAILED";
|
|
|
|
case CONFIRM_TRYING_FAILED:
|
|
|
|
return u"CONFIRM_TRYING_FAILED";
|
|
|
|
case CONFIRM_DISABLED:
|
|
|
|
return u"CONFIRM_DISABLED";
|
|
|
|
}
|
|
|
|
MOZ_ASSERT_UNREACHABLE();
|
|
|
|
return u"";
|
|
|
|
};
|
|
|
|
|
|
|
|
obs->NotifyObservers(nullptr, "network:trr-confirmation",
|
|
|
|
stateString(state));
|
2023-03-26 00:23:18 +03:00
|
|
|
}
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2021-12-02 16:21:55 +03:00
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(XRE_IsSocketProcess());
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
TRRServiceChild* child = TRRServiceChild::GetSingleton();
|
|
|
|
if (child && child->CanSend()) {
|
|
|
|
LOG(("TRRService::SendSetConfirmationState"));
|
|
|
|
Unused << child->SendSetConfirmationState(mState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-21 15:23:19 +03:00
|
|
|
bool TRRService::ConfirmationContext::HandleEvent(ConfirmationEvent aEvent) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(OwningObject()->mLock);
|
2022-02-21 15:23:19 +03:00
|
|
|
return HandleEvent(aEvent, lock);
|
2019-02-01 23:46:00 +03:00
|
|
|
}
|
|
|
|
|
2022-05-13 00:55:01 +03:00
|
|
|
// We're protected by service->mLock
|
|
|
|
bool TRRService::ConfirmationContext::HandleEvent(
|
|
|
|
ConfirmationEvent aEvent, const MutexSingleWriterAutoLock&) {
|
2022-02-21 15:23:19 +03:00
|
|
|
auto prevAddr = TaskAddr();
|
2021-05-03 12:09:18 +03:00
|
|
|
TRRService* service = OwningObject();
|
|
|
|
service->mLock.AssertCurrentThreadOwns();
|
|
|
|
nsIDNSService::ResolverMode mode = service->Mode();
|
2021-02-17 13:26:41 +03:00
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
auto resetConfirmation = [&]() {
|
2022-05-13 00:55:01 +03:00
|
|
|
service->mLock.AssertCurrentThreadOwns();
|
2021-05-03 12:09:18 +03:00
|
|
|
mTask = nullptr;
|
|
|
|
nsCOMPtr<nsITimer> timer = std::move(mTimer);
|
2021-03-19 20:51:26 +03:00
|
|
|
if (timer) {
|
|
|
|
timer->Cancel();
|
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
mRetryInterval = StaticPrefs::network_trr_retry_timeout_ms();
|
|
|
|
mTRRFailures = 0;
|
2021-03-19 20:51:26 +03:00
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
if (TRR_DISABLED(mode)) {
|
|
|
|
LOG(("TRR is disabled. mConfirmation.mState -> CONFIRM_OFF"));
|
2021-12-02 16:21:55 +03:00
|
|
|
SetState(CONFIRM_OFF);
|
2021-03-19 20:51:26 +03:00
|
|
|
return;
|
|
|
|
}
|
2019-02-01 23:46:00 +03:00
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
if (mode == nsIDNSService::MODE_TRRONLY) {
|
|
|
|
LOG(("TRR_ONLY_MODE. mConfirmation.mState -> CONFIRM_DISABLED"));
|
2021-12-02 16:21:55 +03:00
|
|
|
SetState(CONFIRM_DISABLED);
|
2021-03-19 20:51:26 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
if (service->mConfirmationNS.Equals("skip"_ns)) {
|
|
|
|
LOG((
|
|
|
|
"mConfirmationNS == skip. mConfirmation.mState -> CONFIRM_DISABLED"));
|
2021-12-02 16:21:55 +03:00
|
|
|
SetState(CONFIRM_DISABLED);
|
2021-03-19 20:51:26 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The next call to maybeConfirm will transition to CONFIRM_TRYING_OK
|
2021-05-03 12:09:18 +03:00
|
|
|
LOG(("mConfirmation.mState -> CONFIRM_OK"));
|
2021-12-02 16:21:55 +03:00
|
|
|
SetState(CONFIRM_OK);
|
2021-03-19 20:51:26 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
auto maybeConfirm = [&](const char* aReason) {
|
2022-05-13 00:55:01 +03:00
|
|
|
service->mLock.AssertCurrentThreadOwns();
|
2021-05-03 12:09:18 +03:00
|
|
|
if (TRR_DISABLED(mode) || mState == CONFIRM_DISABLED || mTask) {
|
2021-03-19 20:51:26 +03:00
|
|
|
LOG(
|
2021-05-03 12:09:18 +03:00
|
|
|
("TRRService:MaybeConfirm(%s) mode=%d, mTask=%p "
|
|
|
|
"mState=%d\n",
|
|
|
|
aReason, (int)mode, (void*)mTask, (int)mState));
|
2021-03-19 20:51:26 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
MOZ_ASSERT(mode != nsIDNSService::MODE_TRRONLY,
|
2021-03-19 20:51:26 +03:00
|
|
|
"Confirmation should be disabled");
|
2021-05-03 12:09:18 +03:00
|
|
|
MOZ_ASSERT(!service->mConfirmationNS.Equals("skip"),
|
2021-03-19 20:51:26 +03:00
|
|
|
"Confirmation should be disabled");
|
2021-02-17 13:26:41 +03:00
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
LOG(("maybeConfirm(%s) starting confirmation test %s %s\n", aReason,
|
2021-05-03 12:09:18 +03:00
|
|
|
service->mPrivateURI.get(), service->mConfirmationNS.get()));
|
2021-03-19 20:51:26 +03:00
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
MOZ_ASSERT(mState == CONFIRM_OK || mState == CONFIRM_FAILED);
|
2021-03-19 20:51:26 +03:00
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
if (mState == CONFIRM_FAILED) {
|
|
|
|
LOG(("mConfirmation.mState -> CONFIRM_TRYING_FAILED"));
|
2021-12-02 16:21:55 +03:00
|
|
|
SetState(CONFIRM_TRYING_FAILED);
|
2021-03-19 20:51:26 +03:00
|
|
|
} else {
|
2021-05-03 12:09:18 +03:00
|
|
|
LOG(("mConfirmation.mState -> CONFIRM_TRYING_OK"));
|
2021-12-02 16:21:55 +03:00
|
|
|
SetState(CONFIRM_TRYING_OK);
|
2021-03-19 20:51:26 +03:00
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:19 +03:00
|
|
|
nsCOMPtr<nsITimer> timer = std::move(mTimer);
|
|
|
|
if (timer) {
|
|
|
|
timer->Cancel();
|
2021-03-19 20:51:26 +03:00
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
MOZ_ASSERT(mode == nsIDNSService::MODE_TRRFIRST,
|
2021-03-19 20:51:26 +03:00
|
|
|
"Should only confirm in TRR first mode");
|
2022-06-16 12:56:05 +03:00
|
|
|
// Set aUseFreshConnection if TRR lookups are retried.
|
2021-12-02 16:21:53 +03:00
|
|
|
mTask = new TRR(service, service->mConfirmationNS, TRRTYPE_NS, ""_ns, false,
|
2022-06-16 12:56:05 +03:00
|
|
|
StaticPrefs::network_trr_retry_on_recoverable_errors());
|
2021-05-03 12:09:18 +03:00
|
|
|
mTask->SetTimeout(StaticPrefs::network_trr_confirmation_timeout_ms());
|
|
|
|
mTask->SetPurpose(TRR::Confirmation);
|
2021-02-17 13:26:41 +03:00
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
if (service->mLinkService) {
|
|
|
|
service->mLinkService->GetNetworkID(mNetworkId);
|
2021-02-17 13:26:41 +03:00
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
if (mFirstRequestTime.IsNull()) {
|
|
|
|
mFirstRequestTime = TimeStamp::Now();
|
2021-02-17 13:26:41 +03:00
|
|
|
}
|
2021-05-03 12:09:18 +03:00
|
|
|
if (mTrigger.IsEmpty()) {
|
|
|
|
mTrigger.Assign(aReason);
|
2021-02-17 13:26:41 +03:00
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
LOG(("Dispatching confirmation task: %p", mTask.get()));
|
|
|
|
service->DispatchTRRRequestInternal(mTask, false);
|
2021-03-19 20:51:26 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
switch (aEvent) {
|
|
|
|
case ConfirmationEvent::Init:
|
|
|
|
resetConfirmation();
|
|
|
|
maybeConfirm("context-init");
|
|
|
|
break;
|
|
|
|
case ConfirmationEvent::PrefChange:
|
|
|
|
resetConfirmation();
|
|
|
|
maybeConfirm("pref-change");
|
|
|
|
break;
|
2022-06-16 12:56:05 +03:00
|
|
|
case ConfirmationEvent::ConfirmationRetry:
|
2021-05-03 12:09:18 +03:00
|
|
|
MOZ_ASSERT(mState == CONFIRM_FAILED);
|
|
|
|
if (mState == CONFIRM_FAILED) {
|
2022-06-16 12:56:05 +03:00
|
|
|
maybeConfirm("confirmation-retry");
|
2021-03-19 20:51:26 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ConfirmationEvent::FailedLookups:
|
2021-05-03 12:09:18 +03:00
|
|
|
MOZ_ASSERT(mState == CONFIRM_OK);
|
2022-04-22 12:39:31 +03:00
|
|
|
mTrigger.Assign("failed-lookups");
|
|
|
|
mFailedLookups = nsDependentCSubstring(
|
|
|
|
mFailureReasons, mTRRFailures % ConfirmationContext::RESULTS_SIZE);
|
2021-03-19 20:51:26 +03:00
|
|
|
maybeConfirm("failed-lookups");
|
|
|
|
break;
|
2022-06-16 12:56:05 +03:00
|
|
|
case ConfirmationEvent::RetryTRR:
|
2021-12-02 16:21:53 +03:00
|
|
|
MOZ_ASSERT(mState == CONFIRM_OK);
|
2022-06-16 12:56:05 +03:00
|
|
|
maybeConfirm("retry-trr");
|
2021-12-02 16:21:53 +03:00
|
|
|
break;
|
2021-03-19 20:51:26 +03:00
|
|
|
case ConfirmationEvent::URIChange:
|
|
|
|
resetConfirmation();
|
|
|
|
maybeConfirm("uri-change");
|
|
|
|
break;
|
|
|
|
case ConfirmationEvent::CaptivePortalConnectivity:
|
|
|
|
// If we area already confirmed then we're fine.
|
|
|
|
// If there is a confirmation in progress, likely it started before
|
|
|
|
// we had full connectivity, so it may be hanging. We reset and try again.
|
2021-05-03 12:09:18 +03:00
|
|
|
if (mState == CONFIRM_FAILED || mState == CONFIRM_TRYING_FAILED ||
|
|
|
|
mState == CONFIRM_TRYING_OK) {
|
2021-03-19 20:51:26 +03:00
|
|
|
resetConfirmation();
|
|
|
|
maybeConfirm("cp-connectivity");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ConfirmationEvent::NetworkUp:
|
2021-05-03 12:09:18 +03:00
|
|
|
if (mState != CONFIRM_OK) {
|
2021-03-19 20:51:26 +03:00
|
|
|
resetConfirmation();
|
|
|
|
maybeConfirm("network-up");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ConfirmationEvent::ConfirmOK:
|
2021-12-02 16:21:55 +03:00
|
|
|
SetState(CONFIRM_OK);
|
2021-05-03 12:09:18 +03:00
|
|
|
mTask = nullptr;
|
2021-03-19 20:51:26 +03:00
|
|
|
break;
|
|
|
|
case ConfirmationEvent::ConfirmFail:
|
2021-05-03 12:09:18 +03:00
|
|
|
MOZ_ASSERT(mState == CONFIRM_TRYING_OK ||
|
|
|
|
mState == CONFIRM_TRYING_FAILED);
|
2021-12-02 16:21:55 +03:00
|
|
|
SetState(CONFIRM_FAILED);
|
2021-05-03 12:09:18 +03:00
|
|
|
mTask = nullptr;
|
2021-03-19 20:51:26 +03:00
|
|
|
// retry failed NS confirmation
|
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
NS_NewTimerWithCallback(getter_AddRefs(mTimer), this, mRetryInterval,
|
2021-03-19 20:51:26 +03:00
|
|
|
nsITimer::TYPE_ONE_SHOT);
|
2021-05-03 12:09:18 +03:00
|
|
|
if (mRetryInterval < 64000) {
|
2021-03-19 20:51:26 +03:00
|
|
|
// double the interval up to this point
|
2021-05-03 12:09:18 +03:00
|
|
|
mRetryInterval *= 2;
|
2021-03-19 20:51:26 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Unexpected ConfirmationEvent");
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
2022-02-21 15:23:19 +03:00
|
|
|
|
|
|
|
return prevAddr != TaskAddr();
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool TRRService::MaybeBootstrap(const nsACString& aPossible,
|
|
|
|
nsACString& aResult) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2021-01-25 15:22:43 +03:00
|
|
|
if (mMode == nsIDNSService::MODE_TRROFF || mBootstrapAddr.IsEmpty()) {
|
2018-02-01 12:20:49 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> url;
|
|
|
|
nsresult rv =
|
|
|
|
NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID)
|
2021-08-12 10:40:58 +03:00
|
|
|
.Apply(&nsIStandardURLMutator::Init, nsIStandardURL::URLTYPE_STANDARD,
|
|
|
|
443, mPrivateURI, nullptr, nullptr, nullptr)
|
2018-02-01 12:20:49 +03:00
|
|
|
.Finalize(url);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
LOG(("TRRService::MaybeBootstrap failed to create URI!\n"));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoCString host;
|
|
|
|
url->GetHost(host);
|
|
|
|
if (!aPossible.Equals(host)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
LOG(("TRRService::MaybeBootstrap: use %s instead of %s\n",
|
|
|
|
mBootstrapAddr.get(), host.get()));
|
|
|
|
aResult = mBootstrapAddr;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-07-11 22:32:27 +03:00
|
|
|
bool TRRService::IsDomainBlocked(const nsACString& aHost,
|
|
|
|
const nsACString& aOriginSuffix,
|
|
|
|
bool aPrivateBrowsing) {
|
2020-07-11 22:32:45 +03:00
|
|
|
auto bl = mTRRBLStorage.Lock();
|
|
|
|
if (bl->IsEmpty()) {
|
2019-03-21 15:41:41 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
// use a unified casing for the hashkey
|
2018-10-22 18:38:18 +03:00
|
|
|
nsAutoCString hashkey(aHost + aOriginSuffix);
|
2021-03-01 12:59:30 +03:00
|
|
|
if (auto val = bl->Lookup(hashkey)) {
|
2022-01-25 18:57:03 +03:00
|
|
|
int32_t until =
|
|
|
|
*val + int32_t(StaticPrefs::network_trr_temp_blocklist_duration_sec());
|
2018-02-01 12:20:49 +03:00
|
|
|
int32_t expire = NowInSeconds();
|
2020-07-11 22:32:45 +03:00
|
|
|
if (until > expire) {
|
2020-07-11 22:32:27 +03:00
|
|
|
LOG(("Host [%s] is TRR blocklisted\n", nsCString(aHost).get()));
|
2018-02-01 12:20:49 +03:00
|
|
|
return true;
|
2018-04-30 19:46:04 +03:00
|
|
|
}
|
2019-02-01 23:46:00 +03:00
|
|
|
|
2020-07-11 22:32:27 +03:00
|
|
|
// the blocklisted entry has expired
|
2021-03-01 12:59:30 +03:00
|
|
|
val.Remove();
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-07-11 22:32:27 +03:00
|
|
|
// When running in TRR-only mode, the blocklist is not used and it will also
|
2019-11-12 00:11:18 +03:00
|
|
|
// try resolving the localhost / .local names.
|
2020-07-11 22:32:27 +03:00
|
|
|
bool TRRService::IsTemporarilyBlocked(const nsACString& aHost,
|
|
|
|
const nsACString& aOriginSuffix,
|
|
|
|
bool aPrivateBrowsing,
|
|
|
|
bool aParentsToo) // false if domain
|
2019-11-12 00:11:18 +03:00
|
|
|
{
|
2021-12-02 16:21:56 +03:00
|
|
|
if (!StaticPrefs::network_trr_temp_blocklist()) {
|
|
|
|
LOG(("TRRService::IsTemporarilyBlocked temp blocklist disabled by pref"));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-01-25 15:22:43 +03:00
|
|
|
if (mMode == nsIDNSService::MODE_TRRONLY) {
|
2019-11-12 00:11:18 +03:00
|
|
|
return false; // might as well try
|
|
|
|
}
|
|
|
|
|
2020-07-11 22:32:27 +03:00
|
|
|
LOG(("Checking if host [%s] is blocklisted", aHost.BeginReading()));
|
2019-11-12 00:11:18 +03:00
|
|
|
|
|
|
|
int32_t dot = aHost.FindChar('.');
|
|
|
|
if ((dot == kNotFound) && aParentsToo) {
|
|
|
|
// Only if a full host name. Domains can be dotless to be able to
|
2020-07-11 22:32:27 +03:00
|
|
|
// blocklist entire TLDs
|
2019-11-12 00:11:18 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-07-11 22:32:27 +03:00
|
|
|
if (IsDomainBlocked(aHost, aOriginSuffix, aPrivateBrowsing)) {
|
2019-11-12 00:11:18 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsDependentCSubstring domain = Substring(aHost, 0);
|
|
|
|
while (dot != kNotFound) {
|
|
|
|
dot++;
|
|
|
|
domain.Rebind(domain, dot, domain.Length() - dot);
|
|
|
|
|
2020-07-11 22:32:27 +03:00
|
|
|
if (IsDomainBlocked(domain, aOriginSuffix, aPrivateBrowsing)) {
|
2019-11-12 00:11:18 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
dot = domain.FindChar('.');
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-03-28 16:15:05 +03:00
|
|
|
bool TRRService::IsExcludedFromTRR(const nsACString& aHost) {
|
2019-11-21 13:43:02 +03:00
|
|
|
// This method may be called off the main thread. We need to lock so
|
|
|
|
// mExcludedDomains and mDNSSuffixDomains don't change while this code
|
|
|
|
// is running.
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(mLock);
|
2019-11-21 13:43:02 +03:00
|
|
|
|
|
|
|
return IsExcludedFromTRR_unlocked(aHost);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TRRService::IsExcludedFromTRR_unlocked(const nsACString& aHost) {
|
2022-05-13 00:55:01 +03:00
|
|
|
mLock.AssertOnWritingThreadOrHeld();
|
2019-11-21 13:43:02 +03:00
|
|
|
|
2019-07-18 21:02:58 +03:00
|
|
|
int32_t dot = 0;
|
|
|
|
// iteratively check the sub-domain of |aHost|
|
|
|
|
while (dot < static_cast<int32_t>(aHost.Length())) {
|
|
|
|
nsDependentCSubstring subdomain =
|
|
|
|
Substring(aHost, dot, aHost.Length() - dot);
|
|
|
|
|
2021-03-23 13:36:35 +03:00
|
|
|
if (mExcludedDomains.Contains(subdomain)) {
|
2019-07-18 21:02:58 +03:00
|
|
|
LOG(("Subdomain [%s] of host [%s] Is Excluded From TRR via pref\n",
|
|
|
|
subdomain.BeginReading(), aHost.BeginReading()));
|
2019-03-28 16:15:05 +03:00
|
|
|
return true;
|
|
|
|
}
|
2021-03-23 13:36:35 +03:00
|
|
|
if (mDNSSuffixDomains.Contains(subdomain)) {
|
2019-10-15 16:24:49 +03:00
|
|
|
LOG(("Subdomain [%s] of host [%s] Is Excluded From TRR via pref\n",
|
|
|
|
subdomain.BeginReading(), aHost.BeginReading()));
|
|
|
|
return true;
|
|
|
|
}
|
2021-03-23 13:36:35 +03:00
|
|
|
if (mEtcHostsDomains.Contains(subdomain)) {
|
2020-10-01 10:01:58 +03:00
|
|
|
LOG(("Subdomain [%s] of host [%s] Is Excluded From TRR by /etc/hosts\n",
|
|
|
|
subdomain.BeginReading(), aHost.BeginReading()));
|
|
|
|
return true;
|
|
|
|
}
|
2019-07-18 21:02:58 +03:00
|
|
|
|
|
|
|
dot = aHost.FindChar('.', dot + 1);
|
|
|
|
if (dot == kNotFound) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
dot++;
|
2019-03-28 16:15:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-07-11 22:32:27 +03:00
|
|
|
void TRRService::AddToBlocklist(const nsACString& aHost,
|
|
|
|
const nsACString& aOriginSuffix,
|
|
|
|
bool privateBrowsing, bool aParentsToo) {
|
2021-12-02 16:21:56 +03:00
|
|
|
if (!StaticPrefs::network_trr_temp_blocklist()) {
|
|
|
|
LOG(("TRRService::AddToBlocklist temp blocklist disabled by pref"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-11 22:32:27 +03:00
|
|
|
LOG(("TRR blocklist %s\n", nsCString(aHost).get()));
|
2018-10-22 18:38:18 +03:00
|
|
|
nsAutoCString hashkey(aHost + aOriginSuffix);
|
2018-02-01 12:20:49 +03:00
|
|
|
|
|
|
|
// this overwrites any existing entry
|
2020-07-11 22:32:45 +03:00
|
|
|
{
|
|
|
|
auto bl = mTRRBLStorage.Lock();
|
2021-02-26 12:11:46 +03:00
|
|
|
bl->InsertOrUpdate(hashkey, NowInSeconds());
|
2020-07-11 22:32:45 +03:00
|
|
|
}
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2021-06-15 16:59:10 +03:00
|
|
|
// See bug 1700405. Some test expects 15 trr consecutive failures, but the NS
|
|
|
|
// check against the base domain is successful. So, we skip this NS check when
|
|
|
|
// the pref said so in order to pass the test reliably.
|
|
|
|
if (aParentsToo && !StaticPrefs::network_trr_skip_check_for_blocked_host()) {
|
2018-02-01 12:20:49 +03:00
|
|
|
// when given a full host name, verify its domain as well
|
|
|
|
int32_t dot = aHost.FindChar('.');
|
|
|
|
if (dot != kNotFound) {
|
|
|
|
// this has a domain to be checked
|
|
|
|
dot++;
|
|
|
|
nsDependentCSubstring domain =
|
|
|
|
Substring(aHost, dot, aHost.Length() - dot);
|
|
|
|
nsAutoCString check(domain);
|
2020-07-11 22:32:27 +03:00
|
|
|
if (IsTemporarilyBlocked(check, aOriginSuffix, privateBrowsing, false)) {
|
|
|
|
// the domain part is already blocklisted, no need to add this entry
|
2018-02-01 12:20:49 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// verify 'check' over TRR
|
|
|
|
LOG(("TRR: verify if '%s' resolves as NS\n", check.get()));
|
|
|
|
|
|
|
|
// check if there's an NS entry for this name
|
2021-12-02 16:21:53 +03:00
|
|
|
RefPtr<TRR> trr = new TRR(this, check, TRRTYPE_NS, aOriginSuffix,
|
|
|
|
privateBrowsing, false);
|
2021-03-19 20:51:25 +03:00
|
|
|
trr->SetPurpose(TRR::Blocklist);
|
2020-03-04 19:11:16 +03:00
|
|
|
DispatchTRRRequest(trr);
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-09 11:05:48 +03:00
|
|
|
NS_IMETHODIMP
|
2021-05-03 12:09:17 +03:00
|
|
|
TRRService::ConfirmationContext::Notify(nsITimer* aTimer) {
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(OwningObject()->mLock);
|
2021-05-03 12:09:17 +03:00
|
|
|
if (aTimer == mTimer) {
|
2022-06-16 12:56:05 +03:00
|
|
|
HandleEvent(ConfirmationEvent::ConfirmationRetry, lock);
|
2018-03-09 11:05:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2021-09-07 11:01:18 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
TRRService::ConfirmationContext::GetName(nsACString& aName) {
|
|
|
|
aName.AssignLiteral("TRRService::ConfirmationContext");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2021-03-03 17:32:24 +03:00
|
|
|
static char StatusToChar(nsresult aLookupStatus, nsresult aChannelStatus) {
|
|
|
|
// If the resolution fails in the TRR channel then we'll have a failed
|
|
|
|
// aChannelStatus. Otherwise, we parse the response - if it's not a valid DNS
|
|
|
|
// packet or doesn't contain the correct responses aLookupStatus will be a
|
|
|
|
// failure code.
|
|
|
|
if (aChannelStatus == NS_OK) {
|
|
|
|
// Return + if confirmation was OK, or - if confirmation failed
|
|
|
|
return aLookupStatus == NS_OK ? '+' : '-';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsCOMPtr<nsIIOService> ios = do_GetIOService()) {
|
|
|
|
bool hasConnectiviy = true;
|
|
|
|
ios->GetConnectivity(&hasConnectiviy);
|
|
|
|
if (!hasConnectiviy) {
|
|
|
|
// Browser has no active network interfaces = is offline.
|
|
|
|
return 'o';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (aChannelStatus) {
|
|
|
|
case NS_ERROR_NET_TIMEOUT_EXTERNAL:
|
|
|
|
// TRR timeout expired
|
|
|
|
return 't';
|
|
|
|
case NS_ERROR_UNKNOWN_HOST:
|
|
|
|
// TRRServiceChannel failed to due to unresolved host
|
|
|
|
return 'd';
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The error is a network error
|
|
|
|
if (NS_ERROR_GET_MODULE(aChannelStatus) == NS_ERROR_MODULE_NETWORK) {
|
|
|
|
return 'n';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Some other kind of failure.
|
|
|
|
return '?';
|
|
|
|
}
|
|
|
|
|
2022-06-16 12:56:05 +03:00
|
|
|
void TRRService::RetryTRRConfirm() {
|
2021-12-02 16:21:53 +03:00
|
|
|
if (mConfirmation.State() == CONFIRM_OK) {
|
2022-06-16 12:56:05 +03:00
|
|
|
LOG(("TRRService::RetryTRRConfirm triggering confirmation"));
|
|
|
|
mConfirmation.HandleEvent(ConfirmationEvent::RetryTRR);
|
2021-12-02 16:21:53 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-11 12:57:28 +03:00
|
|
|
void TRRService::RecordTRRStatus(TRR* aTrrRequest) {
|
2020-06-22 14:10:21 +03:00
|
|
|
MOZ_ASSERT_IF(XRE_IsParentProcess(), NS_IsMainThread() || IsOnTRRThread());
|
|
|
|
MOZ_ASSERT_IF(XRE_IsSocketProcess(), NS_IsMainThread());
|
2020-03-04 19:11:16 +03:00
|
|
|
|
2023-04-11 12:57:28 +03:00
|
|
|
nsresult channelStatus = aTrrRequest->ChannelStatus();
|
|
|
|
|
2020-05-30 11:39:02 +03:00
|
|
|
Telemetry::AccumulateCategoricalKeyed(
|
2023-04-11 12:57:28 +03:00
|
|
|
ProviderKey(), NS_SUCCEEDED(channelStatus)
|
2021-02-22 16:51:44 +03:00
|
|
|
? Telemetry::LABELS_DNS_TRR_SUCCESS3::Fine
|
2023-04-11 12:57:28 +03:00
|
|
|
: (channelStatus == NS_ERROR_NET_TIMEOUT_EXTERNAL
|
2021-02-22 16:51:44 +03:00
|
|
|
? Telemetry::LABELS_DNS_TRR_SUCCESS3::Timeout
|
|
|
|
: Telemetry::LABELS_DNS_TRR_SUCCESS3::Bad));
|
2021-05-03 12:09:18 +03:00
|
|
|
|
2023-04-11 12:57:28 +03:00
|
|
|
mConfirmation.RecordTRRStatus(aTrrRequest);
|
2021-05-03 12:09:18 +03:00
|
|
|
}
|
|
|
|
|
2023-04-11 12:57:28 +03:00
|
|
|
void TRRService::ConfirmationContext::RecordTRRStatus(TRR* aTrrRequest) {
|
|
|
|
nsresult channelStatus = aTrrRequest->ChannelStatus();
|
|
|
|
|
|
|
|
if (OwningObject()->Mode() == nsIDNSService::MODE_TRRONLY) {
|
|
|
|
mLastConfirmationSkipReason = aTrrRequest->SkipReason();
|
|
|
|
mLastConfirmationStatus = channelStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(channelStatus)) {
|
2021-05-03 12:09:18 +03:00
|
|
|
LOG(("TRRService::RecordTRRStatus channel success"));
|
|
|
|
mTRRFailures = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OwningObject()->Mode() != nsIDNSService::MODE_TRRFIRST) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// only count failures while in OK state
|
|
|
|
if (State() != CONFIRM_OK) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-06-16 12:56:05 +03:00
|
|
|
// When TRR retry is enabled, nsHostResolver will trigger Confirmation
|
|
|
|
// immediately upon a lookup failure, so nothing to be done here.
|
|
|
|
// nsHostResolver can assess the success of the lookup considering all the
|
|
|
|
// involved results (A, AAAA) so we let it tell us when to re-Confirm.
|
|
|
|
if (StaticPrefs::network_trr_retry_on_recoverable_errors()) {
|
|
|
|
LOG(("TRRService not counting failures when retry is enabled"));
|
2021-12-02 16:21:53 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:18 +03:00
|
|
|
mFailureReasons[mTRRFailures % ConfirmationContext::RESULTS_SIZE] =
|
2023-04-11 12:57:28 +03:00
|
|
|
StatusToChar(NS_OK, channelStatus);
|
2021-05-03 12:09:18 +03:00
|
|
|
uint32_t fails = ++mTRRFailures;
|
|
|
|
LOG(("TRRService::RecordTRRStatus fails=%u", fails));
|
|
|
|
|
|
|
|
if (fails >= StaticPrefs::network_trr_max_fails()) {
|
|
|
|
LOG(("TRRService had %u failures in a row\n", fails));
|
|
|
|
// When several failures occur we trigger a confirmation causing
|
|
|
|
// us to transition into the CONFIRM_TRYING_OK state.
|
|
|
|
// Only after the confirmation fails do we finally go into CONFIRM_FAILED
|
|
|
|
// and start skipping TRR.
|
|
|
|
|
|
|
|
// Trigger a confirmation immediately.
|
|
|
|
// If it fails, it will fire off a timer to start retrying again.
|
2021-05-03 12:09:18 +03:00
|
|
|
HandleEvent(ConfirmationEvent::FailedLookups);
|
2018-10-03 14:53:46 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-13 12:34:36 +03:00
|
|
|
void TRRService::ConfirmationContext::RecordEvent(
|
|
|
|
const char* aReason, const MutexSingleWriterAutoLock&) {
|
2021-02-17 13:26:41 +03:00
|
|
|
// Reset the confirmation context attributes
|
|
|
|
// Only resets the attributes that we keep for telemetry purposes.
|
|
|
|
auto reset = [&]() {
|
|
|
|
mAttemptCount = 0;
|
|
|
|
mNetworkId.Truncate();
|
|
|
|
mFirstRequestTime = TimeStamp();
|
|
|
|
mContextChangeReason.Assign(aReason);
|
|
|
|
mTrigger.Truncate();
|
2021-03-03 17:32:24 +03:00
|
|
|
mFailedLookups.Truncate();
|
2021-02-17 13:26:41 +03:00
|
|
|
|
|
|
|
mRetryInterval = StaticPrefs::network_trr_retry_timeout_ms();
|
|
|
|
};
|
|
|
|
|
|
|
|
if (mAttemptCount == 0) {
|
|
|
|
// XXX: resetting everything might not be the best thing here, even if the
|
|
|
|
// context changes, because there might still be a confirmation pending.
|
|
|
|
// But cancelling and retrying that confirmation might just make the whole
|
|
|
|
// confirmation longer for no reason.
|
|
|
|
reset();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Telemetry::EventID eventType =
|
|
|
|
Telemetry::EventID::NetworkDns_Trrconfirmation_Context;
|
|
|
|
|
|
|
|
nsAutoCString results;
|
|
|
|
static_assert(RESULTS_SIZE < 64);
|
|
|
|
|
|
|
|
// mResults is a circular buffer ending at mAttemptCount
|
|
|
|
if (mAttemptCount <= RESULTS_SIZE) {
|
|
|
|
// We have fewer attempts than the size of the buffer, so all of the
|
|
|
|
// results are in the buffer.
|
|
|
|
results.Append(nsDependentCSubstring(mResults, mAttemptCount));
|
|
|
|
} else {
|
|
|
|
// More attempts than the buffer size.
|
|
|
|
// That means past RESULTS_SIZE attempts in order are
|
|
|
|
// [posInResults .. end-of-buffer) + [start-of-buffer .. posInResults)
|
|
|
|
uint32_t posInResults = mAttemptCount % RESULTS_SIZE;
|
|
|
|
|
|
|
|
results.Append(nsDependentCSubstring(mResults + posInResults,
|
|
|
|
RESULTS_SIZE - posInResults));
|
|
|
|
results.Append(nsDependentCSubstring(mResults, posInResults));
|
|
|
|
}
|
|
|
|
|
|
|
|
auto extra = Some<nsTArray<mozilla::Telemetry::EventExtraEntry>>({
|
|
|
|
Telemetry::EventExtraEntry{"trigger"_ns, mTrigger},
|
|
|
|
Telemetry::EventExtraEntry{"contextReason"_ns, mContextChangeReason},
|
|
|
|
Telemetry::EventExtraEntry{"attemptCount"_ns,
|
|
|
|
nsPrintfCString("%u", mAttemptCount)},
|
|
|
|
Telemetry::EventExtraEntry{"results"_ns, results},
|
|
|
|
Telemetry::EventExtraEntry{
|
|
|
|
"time"_ns,
|
|
|
|
nsPrintfCString(
|
|
|
|
"%f",
|
|
|
|
!mFirstRequestTime.IsNull()
|
|
|
|
? (TimeStamp::Now() - mFirstRequestTime).ToMilliseconds()
|
|
|
|
: 0.0)},
|
|
|
|
Telemetry::EventExtraEntry{"networkID"_ns, mNetworkId},
|
|
|
|
Telemetry::EventExtraEntry{"captivePortal"_ns,
|
|
|
|
nsPrintfCString("%i", mCaptivePortalStatus)},
|
|
|
|
});
|
|
|
|
|
2021-03-03 17:32:24 +03:00
|
|
|
if (mTrigger.Equals("failed-lookups"_ns)) {
|
|
|
|
extra.ref().AppendElement(
|
|
|
|
Telemetry::EventExtraEntry{"failedLookups"_ns, mFailedLookups});
|
|
|
|
}
|
|
|
|
|
2021-03-19 20:51:27 +03:00
|
|
|
enum ConfirmationState state = mState;
|
2021-02-17 13:26:41 +03:00
|
|
|
Telemetry::RecordEvent(eventType, mozilla::Some(nsPrintfCString("%u", state)),
|
|
|
|
extra);
|
|
|
|
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TRRService::ConfirmationContext::RequestCompleted(
|
|
|
|
nsresult aLookupStatus, nsresult aChannelStatus) {
|
2021-03-03 17:32:24 +03:00
|
|
|
mResults[mAttemptCount % RESULTS_SIZE] =
|
|
|
|
StatusToChar(aLookupStatus, aChannelStatus);
|
2021-02-17 13:26:41 +03:00
|
|
|
mAttemptCount++;
|
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:17 +03:00
|
|
|
void TRRService::ConfirmationContext::CompleteConfirmation(nsresult aStatus,
|
|
|
|
TRR* aTRRRequest) {
|
2021-03-19 20:51:25 +03:00
|
|
|
{
|
2022-05-13 00:55:01 +03:00
|
|
|
MutexSingleWriterAutoLock lock(OwningObject()->mLock);
|
2021-04-06 15:20:34 +03:00
|
|
|
// Ignore confirmations that dont match the pending task.
|
2021-05-03 12:09:17 +03:00
|
|
|
if (mTask != aTRRRequest) {
|
2021-04-06 15:20:34 +03:00
|
|
|
return;
|
|
|
|
}
|
2021-05-03 12:09:17 +03:00
|
|
|
MOZ_ASSERT(State() == CONFIRM_TRYING_OK ||
|
|
|
|
State() == CONFIRM_TRYING_FAILED);
|
|
|
|
if (State() != CONFIRM_TRYING_OK && State() != CONFIRM_TRYING_FAILED) {
|
2021-04-06 15:20:34 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:17 +03:00
|
|
|
RequestCompleted(aStatus, aTRRRequest->ChannelStatus());
|
2023-04-11 12:57:28 +03:00
|
|
|
mLastConfirmationSkipReason = aTRRRequest->SkipReason();
|
|
|
|
mLastConfirmationStatus = aTRRRequest->ChannelStatus();
|
2021-04-06 15:20:34 +03:00
|
|
|
|
2021-05-03 12:09:17 +03:00
|
|
|
MOZ_ASSERT(mTask);
|
2021-03-19 20:51:26 +03:00
|
|
|
if (NS_SUCCEEDED(aStatus)) {
|
2021-05-03 12:09:18 +03:00
|
|
|
HandleEvent(ConfirmationEvent::ConfirmOK, lock);
|
2021-03-19 20:51:26 +03:00
|
|
|
} else {
|
2021-05-03 12:09:18 +03:00
|
|
|
HandleEvent(ConfirmationEvent::ConfirmFail, lock);
|
2021-03-19 20:51:26 +03:00
|
|
|
}
|
|
|
|
|
2022-04-22 12:39:31 +03:00
|
|
|
if (State() == CONFIRM_OK) {
|
|
|
|
// Record event and start new confirmation context
|
|
|
|
RecordEvent("success", lock);
|
|
|
|
}
|
2021-05-03 12:09:17 +03:00
|
|
|
LOG(("TRRService finishing confirmation test %s %d %X\n",
|
|
|
|
OwningObject()->mPrivateURI.get(), State(), (unsigned int)aStatus));
|
2021-03-19 20:51:25 +03:00
|
|
|
}
|
|
|
|
|
2021-05-03 12:09:17 +03:00
|
|
|
if (State() == CONFIRM_OK) {
|
2021-03-19 20:51:25 +03:00
|
|
|
// A fresh confirmation means previous blocked entries might not
|
|
|
|
// be valid anymore.
|
2021-05-03 12:09:17 +03:00
|
|
|
auto bl = OwningObject()->mTRRBLStorage.Lock();
|
2021-03-19 20:51:25 +03:00
|
|
|
bl->Clear();
|
|
|
|
} else {
|
2021-05-03 12:09:17 +03:00
|
|
|
MOZ_ASSERT(State() == CONFIRM_FAILED);
|
2021-03-19 20:51:25 +03:00
|
|
|
}
|
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
Telemetry::Accumulate(Telemetry::DNS_TRR_NS_VERFIFIED3,
|
2021-05-03 12:09:17 +03:00
|
|
|
TRRService::ProviderKey(), (State() == CONFIRM_OK));
|
2021-03-19 20:51:25 +03:00
|
|
|
}
|
|
|
|
|
2018-02-01 12:20:49 +03:00
|
|
|
AHostResolver::LookupStatus TRRService::CompleteLookup(
|
2018-10-30 16:06:24 +03:00
|
|
|
nsHostRecord* rec, nsresult status, AddrInfo* aNewRRSet, bool pb,
|
2021-02-24 19:37:03 +03:00
|
|
|
const nsACString& aOriginSuffix, TRRSkippedReason aReason,
|
2021-02-17 13:26:41 +03:00
|
|
|
TRR* aTRRRequest) {
|
2020-07-11 22:32:27 +03:00
|
|
|
// this is an NS check for the TRR blocklist or confirmationNS check
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2020-06-22 14:10:21 +03:00
|
|
|
MOZ_ASSERT_IF(XRE_IsParentProcess(), NS_IsMainThread() || IsOnTRRThread());
|
|
|
|
MOZ_ASSERT_IF(XRE_IsSocketProcess(), NS_IsMainThread());
|
2018-02-01 12:20:49 +03:00
|
|
|
MOZ_ASSERT(!rec);
|
|
|
|
|
2019-03-19 15:22:12 +03:00
|
|
|
RefPtr<AddrInfo> newRRSet(aNewRRSet);
|
2021-02-18 15:50:02 +03:00
|
|
|
MOZ_ASSERT(newRRSet && newRRSet->TRRType() == TRRTYPE_NS);
|
2018-02-01 12:20:49 +03:00
|
|
|
|
2021-03-19 20:51:25 +03:00
|
|
|
if (aTRRRequest->Purpose() == TRR::Confirmation) {
|
2021-05-03 12:09:17 +03:00
|
|
|
mConfirmation.CompleteConfirmation(status, aTRRRequest);
|
2021-03-19 20:51:25 +03:00
|
|
|
return LOOKUP_OK;
|
2021-03-19 20:51:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (aTRRRequest->Purpose() == TRR::Blocklist) {
|
2021-03-19 20:51:25 +03:00
|
|
|
if (NS_SUCCEEDED(status)) {
|
|
|
|
LOG(("TRR verified %s to be fine!\n", newRRSet->Hostname().get()));
|
2021-02-17 13:26:41 +03:00
|
|
|
} else {
|
2021-03-19 20:51:25 +03:00
|
|
|
LOG(("TRR says %s doesn't resolve as NS!\n", newRRSet->Hostname().get()));
|
|
|
|
AddToBlocklist(newRRSet->Hostname(), aOriginSuffix, pb, false);
|
2021-02-17 13:26:40 +03:00
|
|
|
}
|
2021-03-19 20:51:26 +03:00
|
|
|
return LOOKUP_OK;
|
2018-02-01 12:20:49 +03:00
|
|
|
}
|
2021-03-19 20:51:25 +03:00
|
|
|
|
2021-03-19 20:51:26 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE(
|
|
|
|
"TRRService::CompleteLookup called for unexpected request");
|
2018-02-01 12:20:49 +03:00
|
|
|
return LOOKUP_OK;
|
|
|
|
}
|
|
|
|
|
2018-09-22 23:54:11 +03:00
|
|
|
AHostResolver::LookupStatus TRRService::CompleteLookupByType(
|
2020-05-04 22:56:51 +03:00
|
|
|
nsHostRecord*, nsresult, mozilla::net::TypeRecordResultType& aResult,
|
|
|
|
uint32_t aTtl, bool aPb) {
|
2018-09-22 23:54:11 +03:00
|
|
|
return LOOKUP_OK;
|
|
|
|
}
|
|
|
|
|
2021-11-29 18:19:15 +03:00
|
|
|
NS_IMETHODIMP TRRService::OnProxyConfigChanged() {
|
|
|
|
LOG(("TRRService::OnProxyConfigChanged"));
|
|
|
|
|
|
|
|
nsAutoCString uri;
|
|
|
|
GetURI(uri);
|
|
|
|
AsyncCreateTRRConnectionInfo(uri);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TRRService::InitTRRConnectionInfo() {
|
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
TRRServiceBase::InitTRRConnectionInfo();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(XRE_IsSocketProcess());
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
TRRServiceChild* child = TRRServiceChild::GetSingleton();
|
|
|
|
if (child && child->CanSend()) {
|
|
|
|
LOG(("TRRService::SendInitTRRConnectionInfo"));
|
|
|
|
Unused << child->SendInitTRRConnectionInfo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-25 18:57:03 +03:00
|
|
|
} // namespace mozilla::net
|