Bug 1828944 - Add TRR mode into TRR provider key, r=valentin,necko-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D176122
This commit is contained in:
Kershaw Chang 2023-04-26 09:16:41 +00:00
parent 35f1c706af
commit f36e52228b
16 changed files with 174 additions and 64 deletions

View File

@ -693,7 +693,8 @@ mozilla::ipc::IPCResult ContentChild::RecvSetXPCOMProcessAttributes(
dont_AddRef(net::ChildDNSService::GetSingleton());
if (dnsServiceChild) {
dnsServiceChild->SetTRRDomain(aXPCOMInit.trrDomain());
dnsServiceChild->SetTRRModeInChild(aXPCOMInit.trrMode());
dnsServiceChild->SetTRRModeInChild(aXPCOMInit.trrMode(),
aXPCOMInit.trrModeFromPref());
}
return IPC_OK();
}
@ -2175,11 +2176,12 @@ mozilla::ipc::IPCResult ContentChild::RecvSetCaptivePortalState(
}
mozilla::ipc::IPCResult ContentChild::RecvSetTRRMode(
const nsIDNSService::ResolverMode& mode) {
const nsIDNSService::ResolverMode& mode,
const nsIDNSService::ResolverMode& modeFromPref) {
RefPtr<net::ChildDNSService> dnsServiceChild =
dont_AddRef(net::ChildDNSService::GetSingleton());
if (dnsServiceChild) {
dnsServiceChild->SetTRRModeInChild(mode);
dnsServiceChild->SetTRRModeInChild(mode, modeFromPref);
}
return IPC_OK();
}

View File

@ -269,7 +269,8 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvSetConnectivity(const bool& connectivity);
mozilla::ipc::IPCResult RecvSetCaptivePortalState(const int32_t& state);
mozilla::ipc::IPCResult RecvSetTRRMode(
const nsIDNSService::ResolverMode& mode);
const nsIDNSService::ResolverMode& mode,
const nsIDNSService::ResolverMode& modeFromPref);
mozilla::ipc::IPCResult RecvBidiKeyboardNotify(const bool& isLangRTL,
const bool& haveBidiKeyboards);

View File

@ -85,6 +85,7 @@
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/StaticPrefs_network.h"
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/StorageAccessAPIHelper.h"
#include "mozilla/StyleSheet.h"
@ -3153,6 +3154,8 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
nsIDNSService::ResolverMode mode;
dns->GetCurrentTrrMode(&mode);
xpcomInit.trrMode() = mode;
xpcomInit.trrModeFromPref() =
static_cast<nsIDNSService::ResolverMode>(StaticPrefs::network_trr_mode());
Unused << SendSetXPCOMProcessAttributes(
xpcomInit, initialData, lnf, fontList, std::move(sharedUASheetHandle),
@ -4150,7 +4153,8 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
nsIDNSService::ResolverMode mode;
dns->GetCurrentTrrMode(&mode);
Unused << SendSetTRRMode(mode);
Unused << SendSetTRRMode(mode, static_cast<nsIDNSService::ResolverMode>(
StaticPrefs::network_trr_mode()));
}
return NS_OK;

View File

@ -371,6 +371,8 @@ struct XPCOMInitData
MetricMask perfStatsMask;
nsCString trrDomain;
ResolverMode trrMode;
// This is the value of network.trr.mode and can be diffrent than trrMode.
ResolverMode trrModeFromPref;
};
struct VisitedQueryResult
@ -658,7 +660,7 @@ child:
async SetOffline(bool offline);
async SetConnectivity(bool connectivity);
async SetCaptivePortalState(int32_t aState);
async SetTRRMode(ResolverMode aMode);
async SetTRRMode(ResolverMode aMode, ResolverMode aModeFromPref);
async NotifyVisited(VisitedQueryResult[] uri);

View File

@ -11876,6 +11876,14 @@
value: 1048576
mirror: always
# DNS Trusted Recursive Resolver
# 0 - default off, 1 - reserved/off, 2 - TRR first, 3 - TRR only,
# 4 - reserved/off, 5 off by choice
- name: network.trr.mode
type: RelaxedAtomicUint32
value: 0
mirror: always
# Default global TRR provider
- name: network.trr.default_provider_uri
type: String

View File

@ -3466,9 +3466,6 @@ pref("network.connectivity-service.DNSv6.domain", "example.org");
pref("network.connectivity-service.IPv4.url", "http://detectportal.firefox.com/success.txt?ipv4");
pref("network.connectivity-service.IPv6.url", "http://detectportal.firefox.com/success.txt?ipv6");
// DNS Trusted Recursive Resolver
// 0 - default off, 1 - reserved/off, 2 - TRR first, 3 - TRR only, 4 - reserved/off, 5 off by choice
pref("network.trr.mode", 0);
pref("network.trr.uri", "");
// credentials to pass to DOH end-point
pref("network.trr.credentials", "");

View File

@ -350,14 +350,15 @@ ChildDNSService::GetCurrentTrrMode(nsIDNSService::ResolverMode* aMode) {
return NS_OK;
}
NS_IMETHODIMP
ChildDNSService::SetTRRModeInChild(nsIDNSService::ResolverMode mode) {
void ChildDNSService::SetTRRModeInChild(
nsIDNSService::ResolverMode mode,
nsIDNSService::ResolverMode modeFromPref) {
if (!XRE_IsContentProcess()) {
MOZ_ASSERT(false, "Why are we calling this?");
return NS_ERROR_NOT_AVAILABLE;
return;
}
mTRRMode = mode;
return NS_OK;
TRRService::SetCurrentTRRMode(modeFromPref);
}
NS_IMETHODIMP

View File

@ -37,6 +37,8 @@ class ChildDNSService final : public DNSServiceBase, public nsPIDNSService {
void SetTRRDomain(const nsACString& aTRRDomain);
void GetTRRDomainKey(nsACString& aTRRDomain);
void SetTRRModeInChild(nsIDNSService::ResolverMode mode,
nsIDNSService::ResolverMode modeFromPref);
private:
virtual ~ChildDNSService() = default;

View File

@ -43,9 +43,12 @@ StaticRefPtr<nsIThread> sTRRBackgroundThread;
static Atomic<TRRService*> sTRRServicePtr;
static Atomic<size_t, Relaxed> sDomainIndex(0);
static Atomic<size_t, Relaxed> sCurrentTRRModeIndex(0);
constexpr nsLiteralCString kTRRDomains[] = {
constexpr nsLiteralCString kTRRDomains[3][7] = {
// clang-format off
{
// When mode is 0, the provider key has no postfix.
"(other)"_ns,
"mozilla.cloudflare-dns.com"_ns,
"firefox.dns.nextdns.io"_ns,
@ -53,13 +56,45 @@ constexpr nsLiteralCString kTRRDomains[] = {
"doh.xfinity.com"_ns, // Steered clients
"dns.shaw.ca"_ns, // Steered clients
"dooh.cloudflare-dns.com"_ns, // DNS over Oblivious HTTP
},
{
"(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
},
// clang-format on
};
// 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)];
}
// static
void TRRService::SetProviderDomain(const nsACString& aTRRDomain) {
sDomainIndex = 0;
for (size_t i = 1; i < std::size(kTRRDomains); i++) {
if (aTRRDomain.Equals(kTRRDomains[i])) {
for (size_t i = 1; i < std::size(kTRRDomains[0]); i++) {
if (aTRRDomain.Equals(kTRRDomains[0][i])) {
sDomainIndex = i;
break;
}
@ -67,7 +102,9 @@ void TRRService::SetProviderDomain(const nsACString& aTRRDomain) {
}
// static
const nsCString& TRRService::ProviderKey() { return kTRRDomains[sDomainIndex]; }
const nsCString& TRRService::ProviderKey() {
return kTRRDomains[sCurrentTRRModeIndex][sDomainIndex];
}
NS_IMPL_ISUPPORTS_INHERITED(TRRService, TRRServiceBase, nsIObserver,
nsISupportsWeakReference)

View File

@ -97,6 +97,8 @@ class TRRService : public TRRServiceBase,
// If the DoH server is not one of the built-in ones it will return "(other)"
static const nsCString& ProviderKey();
static void SetProviderDomain(const nsACString& aTRRDomain);
// Only called when TRR mode changed.
static void SetCurrentTRRMode(nsIDNSService::ResolverMode aMode);
void InitTRRConnectionInfo() override;

View File

@ -6,6 +6,7 @@
#include "TRRServiceBase.h"
#include "TRRService.h"
#include "mozilla/Preferences.h"
#include "mozilla/ScopeExit.h"
#include "nsHostResolver.h"
@ -113,7 +114,8 @@ void TRRServiceBase::CheckURIPrefs() {
}
// static
nsIDNSService::ResolverMode ModeFromPrefs() {
nsIDNSService::ResolverMode ModeFromPrefs(
nsIDNSService::ResolverMode& aTRRModePrefValue) {
// 0 - off, 1 - reserved, 2 - TRR first, 3 - TRR only, 4 - reserved,
// 5 - explicit off
@ -131,6 +133,7 @@ nsIDNSService::ResolverMode ModeFromPrefs() {
tmp = 0;
}
nsIDNSService::ResolverMode modeFromPref = processPrefValue(tmp);
aTRRModePrefValue = modeFromPref;
if (modeFromPref != nsIDNSService::MODE_NATIVEONLY) {
return modeFromPref;
@ -146,13 +149,17 @@ nsIDNSService::ResolverMode ModeFromPrefs() {
void TRRServiceBase::OnTRRModeChange() {
uint32_t oldMode = mMode;
mMode = ModeFromPrefs();
// This is the value of the pref "network.trr.mode"
nsIDNSService::ResolverMode trrModePrefValue;
mMode = ModeFromPrefs(trrModePrefValue);
if (mMode != oldMode) {
LOG(("TRR Mode changed from %d to %d", oldMode, int(mMode)));
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->NotifyObservers(nullptr, NS_NETWORK_TRR_MODE_CHANGED_TOPIC, nullptr);
}
TRRService::SetCurrentTRRMode(trrModePrefValue);
}
static bool readHosts = false;

View File

@ -1473,12 +1473,6 @@ nsDNSService::GetCurrentTrrURI(nsACString& aURI) {
return NS_OK;
}
NS_IMETHODIMP
nsDNSService::SetTRRModeInChild(nsIDNSService::ResolverMode mode) {
MOZ_ASSERT(false, "Why are we calling this?");
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsDNSService::GetCurrentTrrMode(nsIDNSService::ResolverMode* aMode) {
*aMode = nsIDNSService::MODE_NATIVEONLY; // The default mode.

View File

@ -313,55 +313,52 @@ void AddrHostRecord::ResolveComplete() {
: Telemetry::LABELS_DNS_LOOKUP_DISPOSITION3::trrFail);
}
if (nsHostResolver::Mode() == nsIDNSService::MODE_TRRFIRST) {
MOZ_ASSERT(mTRRSkippedReason != mozilla::net::TRRSkippedReason::TRR_UNSET);
MOZ_ASSERT(mTRRSkippedReason != mozilla::net::TRRSkippedReason::TRR_UNSET);
Telemetry::Accumulate(Telemetry::TRR_SKIP_REASON_TRR_FIRST2,
Telemetry::Accumulate(Telemetry::TRR_SKIP_REASON_TRR_FIRST2,
TRRService::ProviderKey(),
static_cast<uint32_t>(mTRRSkippedReason));
if (!mTRRSuccess && LoadNativeUsed()) {
Telemetry::Accumulate(
mNativeSuccess ? Telemetry::TRR_SKIP_REASON_NATIVE_SUCCESS
: Telemetry::TRR_SKIP_REASON_NATIVE_FAILED,
TRRService::ProviderKey(), static_cast<uint32_t>(mTRRSkippedReason));
}
if (IsRelevantTRRSkipReason(mTRRSkippedReason)) {
Telemetry::Accumulate(Telemetry::TRR_RELEVANT_SKIP_REASON_TRR_FIRST,
TRRService::ProviderKey(),
static_cast<uint32_t>(mTRRSkippedReason));
if (!mTRRSuccess && LoadNativeUsed()) {
Telemetry::Accumulate(
mNativeSuccess ? Telemetry::TRR_SKIP_REASON_NATIVE_SUCCESS
: Telemetry::TRR_SKIP_REASON_NATIVE_FAILED,
mNativeSuccess ? Telemetry::TRR_RELEVANT_SKIP_REASON_NATIVE_SUCCESS
: Telemetry::TRR_RELEVANT_SKIP_REASON_NATIVE_FAILED,
TRRService::ProviderKey(), static_cast<uint32_t>(mTRRSkippedReason));
}
}
if (IsRelevantTRRSkipReason(mTRRSkippedReason)) {
Telemetry::Accumulate(Telemetry::TRR_RELEVANT_SKIP_REASON_TRR_FIRST,
if (StaticPrefs::network_trr_retry_on_recoverable_errors() &&
nsHostResolver::Mode() == nsIDNSService::MODE_TRRFIRST) {
nsAutoCString telemetryKey(TRRService::ProviderKey());
if (mFirstTRRSkippedReason != mozilla::net::TRRSkippedReason::TRR_UNSET) {
telemetryKey.AppendLiteral("|");
telemetryKey.AppendInt(static_cast<uint32_t>(mFirstTRRSkippedReason));
Telemetry::Accumulate(mTRRSuccess
? Telemetry::TRR_SKIP_REASON_RETRY_SUCCESS
: Telemetry::TRR_SKIP_REASON_RETRY_FAILED,
TRRService::ProviderKey(),
static_cast<uint32_t>(mTRRSkippedReason));
if (!mTRRSuccess && LoadNativeUsed()) {
Telemetry::Accumulate(
mNativeSuccess ? Telemetry::TRR_RELEVANT_SKIP_REASON_NATIVE_SUCCESS
: Telemetry::TRR_RELEVANT_SKIP_REASON_NATIVE_FAILED,
TRRService::ProviderKey(),
static_cast<uint32_t>(mTRRSkippedReason));
}
static_cast<uint32_t>(mFirstTRRSkippedReason));
}
if (StaticPrefs::network_trr_retry_on_recoverable_errors()) {
nsAutoCString telemetryKey(TRRService::ProviderKey());
Telemetry::Accumulate(Telemetry::TRR_SKIP_REASON_STRICT_MODE, telemetryKey,
static_cast<uint32_t>(mTRRSkippedReason));
if (mFirstTRRSkippedReason != mozilla::net::TRRSkippedReason::TRR_UNSET) {
telemetryKey.AppendLiteral("|");
telemetryKey.AppendInt(static_cast<uint32_t>(mFirstTRRSkippedReason));
Telemetry::Accumulate(mTRRSuccess
? Telemetry::TRR_SKIP_REASON_RETRY_SUCCESS
: Telemetry::TRR_SKIP_REASON_RETRY_FAILED,
TRRService::ProviderKey(),
static_cast<uint32_t>(mFirstTRRSkippedReason));
}
Telemetry::Accumulate(Telemetry::TRR_SKIP_REASON_STRICT_MODE,
telemetryKey,
static_cast<uint32_t>(mTRRSkippedReason));
if (mTRRSuccess) {
Telemetry::Accumulate(Telemetry::TRR_ATTEMPT_COUNT,
TRRService::ProviderKey(), mTrrAttempts);
}
if (mTRRSuccess) {
Telemetry::Accumulate(Telemetry::TRR_ATTEMPT_COUNT,
TRRService::ProviderKey(), mTrrAttempts);
}
}

View File

@ -328,8 +328,6 @@ interface nsIDNSService : nsISupports
*/
readonly attribute nsIDNSService_ResolverMode currentTrrMode;
void setTRRModeInChild(in nsIDNSService_ResolverMode mode);
/**
* The TRRService's current confirmation state.
* This is mostly for testing purposes.

View File

@ -0,0 +1,53 @@
"use strict";
/* import-globals-from trr_common.js */
const { TelemetryTestUtils } = ChromeUtils.import(
"resource://testing-common/TelemetryTestUtils.jsm"
);
function setup() {
h2Port = trr_test_setup();
runningODoHTests = false;
}
let TRR_OK = 1;
setup();
registerCleanupFunction(async () => {
trr_clear_prefs();
});
async function trrLookup(mode, rolloutMode) {
let hist = TelemetryTestUtils.getAndClearKeyedHistogram(
"TRR_SKIP_REASON_TRR_FIRST2"
);
if (rolloutMode) {
info("Testing doh-rollout.mode");
setModeAndURI(0, "doh?responseIP=2.2.2.2");
Services.prefs.setIntPref("doh-rollout.mode", rolloutMode);
} else {
setModeAndURI(mode, "doh?responseIP=2.2.2.2");
}
Services.dns.clearCache(true);
await new TRRDNSListener("test.example.com", "2.2.2.2");
let expectedKey = `(other)_${mode}`;
if (mode == 0) {
expectedKey = "(other)";
}
TelemetryTestUtils.assertKeyedHistogramValue(hist, expectedKey, TRR_OK, 1);
}
add_task(async function test_trr_lookup_mode_2() {
await trrLookup(2);
});
add_task(async function test_trr_lookup_mode_3() {
await trrLookup(3);
});
add_task(async function test_trr_lookup_mode_0() {
await trrLookup(0, 2);
});

View File

@ -767,3 +767,8 @@ skip-if =
os == 'android'
os == 'win' && msix # https://bugzilla.mozilla.org/show_bug.cgi?id=1808049
run-sequentially = node server exceptions dont replay well
[test_trr_telemetry.js]
head = head_channels.js head_cache.js head_cookies.js head_trr.js head_http3.js trr_common.js
skip-if =
os == 'android'
socketprocess_networking