mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1649143 - Record telemetry with reason we fell back to Do53 r=dragana,necko-reviewers
This patch attempts to record the reason why we fall back to DNS. I considered using categorical probes for this, but they have a max limit of 20 categories, so we have to use a linear probe. I chose 50 buckets to allow us to add more failure reasons in the future. The recorded values are defined in nsHostRecord::TRRSkippedReason. nsHostRecord::RecordReason is called whenever we encounter a condition that will cause us to skip TRR in nsHostResolver. For failures that occur inside TRR.cpp, each TRR object holds its own reason that is recorded in a similar way. When all TRR requests are complete we report the one that failed (or if both failed we report the one for the A request). Due to the fact that we might also follow CNAME requests, and the final TRR request might not be the one that was issued at first, TRR requests must pass back the reason as an argument to CompleteLookup. Finally, this patch records the reason in two probes: TRR_SKIP_REASON_TRR_FIRST - only reported in TRR-first mode TRR_SKIP_REASON_DNS_WORKED - only reported in TRR-first mode when the fallback DNS request succeeded. This allows us to filter for complete network failures. Differential Revision: https://phabricator.services.mozilla.com/D82168
This commit is contained in:
parent
6a3156ccfa
commit
4106c61ff1
@ -167,6 +167,7 @@ TRR::Run() {
|
||||
MOZ_ASSERT_IF(XRE_IsSocketProcess(), NS_IsMainThread());
|
||||
|
||||
if ((gTRRService == nullptr) || NS_FAILED(SendHTTPRequest())) {
|
||||
RecordReason(nsHostRecord::TRR_SEND_FAILED);
|
||||
FailData(NS_ERROR_FAILURE);
|
||||
// The dtor will now be run
|
||||
}
|
||||
@ -254,6 +255,8 @@ nsresult TRR::SendHTTPRequest() {
|
||||
Telemetry::Accumulate(Telemetry::DNS_TRR_BLACKLISTED2,
|
||||
TRRService::AutoDetectedKey(), true);
|
||||
}
|
||||
|
||||
RecordReason(nsHostRecord::TRR_HOST_BLOCKED_TEMPORARY);
|
||||
// not really an error but no TRR is issued
|
||||
return NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
@ -646,6 +649,42 @@ TRR::OnPush(nsIHttpChannel* associated, nsIHttpChannel* pushed) {
|
||||
NS_IMETHODIMP
|
||||
TRR::OnStartRequest(nsIRequest* aRequest) {
|
||||
LOG(("TRR::OnStartRequest %p %s %d\n", this, mHost.get(), mType));
|
||||
|
||||
nsresult status = NS_OK;
|
||||
aRequest->GetStatus(&status);
|
||||
|
||||
if (NS_FAILED(status)) {
|
||||
if (NS_IsOffline()) {
|
||||
RecordReason(nsHostRecord::TRR_IS_OFFLINE);
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case NS_ERROR_UNKNOWN_HOST:
|
||||
RecordReason(nsHostRecord::TRR_CHANNEL_DNS_FAIL);
|
||||
break;
|
||||
case NS_ERROR_OFFLINE:
|
||||
RecordReason(nsHostRecord::TRR_IS_OFFLINE);
|
||||
break;
|
||||
case NS_ERROR_NET_RESET:
|
||||
RecordReason(nsHostRecord::TRR_NET_RESET);
|
||||
break;
|
||||
case NS_ERROR_NET_TIMEOUT:
|
||||
RecordReason(nsHostRecord::TRR_NET_TIMEOUT);
|
||||
break;
|
||||
case NS_ERROR_PROXY_CONNECTION_REFUSED:
|
||||
RecordReason(nsHostRecord::TRR_NET_REFUSED);
|
||||
break;
|
||||
case NS_ERROR_NET_INTERRUPT:
|
||||
RecordReason(nsHostRecord::TRR_NET_INTERRUPT);
|
||||
break;
|
||||
case NS_ERROR_NET_INADEQUATE_SECURITY:
|
||||
RecordReason(nsHostRecord::TRR_NET_INADEQ_SEQURITY);
|
||||
break;
|
||||
default:
|
||||
RecordReason(nsHostRecord::TRR_UNKNOWN_CHANNEL_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1264,7 +1303,8 @@ nsresult TRR::ReturnData(nsIChannel* aChannel) {
|
||||
if (!mHostResolver) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
(void)mHostResolver->CompleteLookup(mRec, NS_OK, ai, mPB, mOriginSuffix);
|
||||
(void)mHostResolver->CompleteLookup(mRec, NS_OK, ai, mPB, mOriginSuffix,
|
||||
mTRRSkippedReason);
|
||||
mHostResolver = nullptr;
|
||||
mRec = nullptr;
|
||||
} else {
|
||||
@ -1278,6 +1318,9 @@ nsresult TRR::FailData(nsresult error) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// If we didn't record a reason until now, record a default one.
|
||||
RecordReason(nsHostRecord::TRR_FAILED);
|
||||
|
||||
if (mType == TRRTYPE_TXT || mType == TRRTYPE_HTTPSSVC) {
|
||||
TypeRecordResultType empty(Nothing{});
|
||||
(void)mHostResolver->CompleteLookupByType(mRec, error, empty, 0, mPB);
|
||||
@ -1286,7 +1329,8 @@ nsresult TRR::FailData(nsresult error) {
|
||||
// this comes from TRR
|
||||
RefPtr<AddrInfo> ai = new AddrInfo(mHost, mType);
|
||||
|
||||
(void)mHostResolver->CompleteLookup(mRec, error, ai, mPB, mOriginSuffix);
|
||||
(void)mHostResolver->CompleteLookup(mRec, error, ai, mPB, mOriginSuffix,
|
||||
mTRRSkippedReason);
|
||||
}
|
||||
|
||||
mHostResolver = nullptr;
|
||||
@ -1341,6 +1385,7 @@ nsresult TRR::On200Response(nsIChannel* aChannel) {
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("TRR::On200Response DohDecode %x\n", (int)rv));
|
||||
RecordReason(nsHostRecord::TRR_DECODE_FAILED);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1421,10 +1466,12 @@ TRR::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
|
||||
if (NS_SUCCEEDED(rv) && httpStatus == 200) {
|
||||
rv = On200Response(channel);
|
||||
if (NS_SUCCEEDED(rv) && UseDefaultServer()) {
|
||||
RecordReason(nsHostRecord::TRR_OK);
|
||||
RecordProcessingTime(channel);
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
RecordReason(nsHostRecord::TRR_SERVER_RESPONSE_ERR);
|
||||
LOG(("TRR:OnStopRequest:%d %p rv %x httpStatus %d\n", __LINE__, this,
|
||||
(int)rv, httpStatus));
|
||||
}
|
||||
@ -1534,6 +1581,7 @@ void TRR::Cancel() {
|
||||
}
|
||||
|
||||
if (mChannel) {
|
||||
RecordReason(nsHostRecord::TRR_TIMEOUT);
|
||||
LOG(("TRR: %p canceling Channel %p %s %d\n", this, mChannel.get(),
|
||||
mHost.get(), mType));
|
||||
mChannel->Cancel(NS_ERROR_ABORT);
|
||||
|
@ -180,6 +180,13 @@ class TRR : public Runnable,
|
||||
uint32_t mTTL = UINT32_MAX;
|
||||
TypeRecordResultType mResult = mozilla::AsVariant(Nothing());
|
||||
|
||||
nsHostRecord::TRRSkippedReason mTRRSkippedReason = nsHostRecord::TRR_UNSET;
|
||||
void RecordReason(nsHostRecord::TRRSkippedReason reason) {
|
||||
if (mTRRSkippedReason == nsHostRecord::TRR_UNSET) {
|
||||
mTRRSkippedReason = reason;
|
||||
}
|
||||
}
|
||||
|
||||
// keep a copy of the originSuffix for the cases where mRec == nullptr */
|
||||
const nsCString mOriginSuffix;
|
||||
};
|
||||
|
@ -950,7 +950,7 @@ void TRRService::TRRIsOkay(enum TrrOkay aReason) {
|
||||
|
||||
AHostResolver::LookupStatus TRRService::CompleteLookup(
|
||||
nsHostRecord* rec, nsresult status, AddrInfo* aNewRRSet, bool pb,
|
||||
const nsACString& aOriginSuffix) {
|
||||
const nsACString& aOriginSuffix, nsHostRecord::TRRSkippedReason aReason) {
|
||||
// this is an NS check for the TRR blacklist or confirmationNS check
|
||||
|
||||
MOZ_ASSERT_IF(XRE_IsParentProcess(), NS_IsMainThread() || IsOnTRRThread());
|
||||
|
@ -54,8 +54,8 @@ class TRRService : public TRRServiceBase,
|
||||
uint32_t GetRequestTimeout();
|
||||
|
||||
LookupStatus CompleteLookup(nsHostRecord*, nsresult, mozilla::net::AddrInfo*,
|
||||
bool pb,
|
||||
const nsACString& aOriginSuffix) override;
|
||||
bool pb, const nsACString& aOriginSuffix,
|
||||
nsHostRecord::TRRSkippedReason aReason) override;
|
||||
LookupStatus CompleteLookupByType(nsHostRecord*, nsresult,
|
||||
mozilla::net::TypeRecordResultType&,
|
||||
uint32_t, bool pb) override;
|
||||
|
@ -145,10 +145,6 @@ static inline bool IsLowPriority(uint16_t flags) {
|
||||
return flags & nsHostResolver::RES_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
static nsIRequest::TRRMode EffectiveTRRMode(const nsCString& aHost,
|
||||
ResolverMode aResolverMode,
|
||||
nsIRequest::TRRMode aRequestMode);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// this macro filters out any flags that are not used when constructing the
|
||||
// host key. the significant flags are those that would affect the resulting
|
||||
@ -452,6 +448,16 @@ void AddrHostRecord::ResolveComplete() {
|
||||
}
|
||||
}
|
||||
|
||||
if (nsHostResolver::Mode() == MODE_TRRFIRST) {
|
||||
Telemetry::Accumulate(Telemetry::TRR_SKIP_REASON_TRR_FIRST,
|
||||
mTRRTRRSkippedReason);
|
||||
|
||||
if (mNativeSuccess) {
|
||||
Telemetry::Accumulate(Telemetry::TRR_SKIP_REASON_DNS_WORKED,
|
||||
mTRRTRRSkippedReason);
|
||||
}
|
||||
}
|
||||
|
||||
if (mEffectiveTRRMode == nsIRequest::TRR_FIRST_MODE) {
|
||||
if (flags & nsIDNSService::RESOLVE_DISABLE_TRR) {
|
||||
// TRR is disabled on request, which is a next-level back-off method.
|
||||
@ -717,8 +723,8 @@ void nsHostResolver::ClearPendingQueue(
|
||||
for (RefPtr<nsHostRecord> rec : aPendingQ) {
|
||||
rec->Cancel();
|
||||
if (rec->IsAddrRecord()) {
|
||||
CompleteLookup(rec, NS_ERROR_ABORT, nullptr, rec->pb,
|
||||
rec->originSuffix);
|
||||
CompleteLookup(rec, NS_ERROR_ABORT, nullptr, rec->pb, rec->originSuffix,
|
||||
rec->mTRRTRRSkippedReason);
|
||||
} else {
|
||||
mozilla::net::TypeRecordResultType empty(Nothing{});
|
||||
CompleteLookupByType(rec, NS_ERROR_ABORT, empty, 0, rec->pb);
|
||||
@ -924,8 +930,10 @@ nsresult nsHostResolver::ResolveHost(const nsACString& aHost,
|
||||
// and return. otherwise, add ourselves as first pending
|
||||
// callback, and proceed to do the lookup.
|
||||
|
||||
bool excludedFromTRR = false;
|
||||
if (gTRRService && gTRRService->IsExcludedFromTRR(host)) {
|
||||
flags |= RES_DISABLE_TRR;
|
||||
excludedFromTRR = true;
|
||||
|
||||
if (!aTrrServer.IsEmpty()) {
|
||||
return NS_ERROR_UNKNOWN_HOST;
|
||||
@ -949,6 +957,10 @@ nsresult nsHostResolver::ResolveHost(const nsACString& aHost,
|
||||
MOZ_ASSERT((IS_ADDR_TYPE(type) && rec->IsAddrRecord() && addrRec) ||
|
||||
(IS_OTHER_TYPE(type) && !rec->IsAddrRecord()));
|
||||
|
||||
if (excludedFromTRR) {
|
||||
rec->RecordReason(nsHostRecord::TRR_EXCLUDED);
|
||||
}
|
||||
|
||||
// Check if the entry is vaild.
|
||||
if (!(flags & RES_BYPASS_CACHE) &&
|
||||
rec->HasUsableResult(TimeStamp::NowLoRes(), flags)) {
|
||||
@ -1291,6 +1303,7 @@ nsresult nsHostResolver::TrrLookup(nsHostRecord* aRec, TRR* pushedTRR) {
|
||||
nsIRequest::TRRMode reqMode = rec->mEffectiveTRRMode;
|
||||
if (rec->mTrrServer.IsEmpty() &&
|
||||
(!gTRRService || !gTRRService->Enabled(reqMode))) {
|
||||
rec->RecordReason(nsHostRecord::TRR_NOT_CONFIRMED);
|
||||
LOG(("TrrLookup:: %s service not enabled\n", rec->host.get()));
|
||||
return NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
@ -1382,6 +1395,9 @@ nsresult nsHostResolver::TrrLookup(nsHostRecord* aRec, TRR* pushedTRR) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!madeQuery) {
|
||||
rec->RecordReason(nsHostRecord::TRR_DID_NOT_MAKE_QUERY);
|
||||
}
|
||||
return madeQuery ? NS_OK : NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
@ -1454,6 +1470,7 @@ nsresult nsHostResolver::NativeLookup(nsHostRecord* aRec) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
ResolverMode nsHostResolver::Mode() {
|
||||
if (gTRRService) {
|
||||
return static_cast<ResolverMode>(gTRRService->Mode());
|
||||
@ -1468,42 +1485,72 @@ nsIRequest::TRRMode nsHostRecord::TRRMode() {
|
||||
return nsIDNSService::GetTRRModeFromFlags(flags);
|
||||
}
|
||||
|
||||
static nsIRequest::TRRMode EffectiveTRRMode(const nsCString& aHost,
|
||||
ResolverMode aResolverMode,
|
||||
nsIRequest::TRRMode aRequestMode) {
|
||||
// static
|
||||
void nsHostResolver::ComputeEffectiveTRRMode(nsHostRecord* aRec) {
|
||||
ResolverMode resolverMode = nsHostResolver::Mode();
|
||||
nsIRequest::TRRMode requestMode = aRec->TRRMode();
|
||||
|
||||
// For domains that are excluded from TRR or when parental control is enabled,
|
||||
// we fallback to NativeLookup. This happens even in MODE_TRRONLY. By default
|
||||
// localhost and local are excluded (so we cover *.local hosts) See the
|
||||
// network.trr.excluded-domains pref.
|
||||
bool skipTRR = true;
|
||||
if (gTRRService) {
|
||||
skipTRR = gTRRService->IsExcludedFromTRR(aHost) ||
|
||||
(gTRRService->SkipTRRWhenParentalControlEnabled() &&
|
||||
gTRRService->ParentalControlEnabled());
|
||||
}
|
||||
|
||||
if (!gTRRService) {
|
||||
return aRequestMode;
|
||||
aRec->RecordReason(nsHostRecord::TRR_NO_GSERVICE);
|
||||
aRec->mEffectiveTRRMode = requestMode;
|
||||
return;
|
||||
}
|
||||
|
||||
if (skipTRR || aResolverMode == MODE_TRROFF ||
|
||||
aRequestMode == nsIRequest::TRR_DISABLED_MODE ||
|
||||
(aRequestMode == nsIRequest::TRR_DEFAULT_MODE &&
|
||||
aResolverMode == MODE_NATIVEONLY)) {
|
||||
return nsIRequest::TRR_DISABLED_MODE;
|
||||
if (!aRec->mTrrServer.IsEmpty()) {
|
||||
aRec->mEffectiveTRRMode = nsIRequest::TRR_ONLY_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (aRequestMode == nsIRequest::TRR_DEFAULT_MODE &&
|
||||
aResolverMode == MODE_TRRFIRST) {
|
||||
return nsIRequest::TRR_FIRST_MODE;
|
||||
if (gTRRService->IsExcludedFromTRR(aRec->host)) {
|
||||
aRec->RecordReason(nsHostRecord::TRR_EXCLUDED);
|
||||
aRec->mEffectiveTRRMode = nsIRequest::TRR_DISABLED_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (aRequestMode == nsIRequest::TRR_DEFAULT_MODE &&
|
||||
aResolverMode == MODE_TRRONLY) {
|
||||
return nsIRequest::TRR_ONLY_MODE;
|
||||
if (gTRRService->SkipTRRWhenParentalControlEnabled() &&
|
||||
gTRRService->ParentalControlEnabled()) {
|
||||
aRec->RecordReason(nsHostRecord::TRR_PARENTAL_CONTROL);
|
||||
aRec->mEffectiveTRRMode = nsIRequest::TRR_DISABLED_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
return aRequestMode;
|
||||
if (resolverMode == MODE_TRROFF) {
|
||||
aRec->RecordReason(nsHostRecord::TRR_OFF_EXPLICIT);
|
||||
aRec->mEffectiveTRRMode = nsIRequest::TRR_DISABLED_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestMode == nsIRequest::TRR_DISABLED_MODE) {
|
||||
aRec->RecordReason(nsHostRecord::TRR_REQ_MODE_DISABLED);
|
||||
aRec->mEffectiveTRRMode = nsIRequest::TRR_DISABLED_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((requestMode == nsIRequest::TRR_DEFAULT_MODE &&
|
||||
resolverMode == MODE_NATIVEONLY)) {
|
||||
aRec->RecordReason(nsHostRecord::TRR_MODE_NOT_ENABLED);
|
||||
aRec->mEffectiveTRRMode = nsIRequest::TRR_DISABLED_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestMode == nsIRequest::TRR_DEFAULT_MODE &&
|
||||
resolverMode == MODE_TRRFIRST) {
|
||||
aRec->mEffectiveTRRMode = nsIRequest::TRR_FIRST_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestMode == nsIRequest::TRR_DEFAULT_MODE &&
|
||||
resolverMode == MODE_TRRONLY) {
|
||||
aRec->mEffectiveTRRMode = nsIRequest::TRR_ONLY_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
aRec->mEffectiveTRRMode = requestMode;
|
||||
}
|
||||
|
||||
// Kick-off a name resolve operation, using native resolver and/or TRR
|
||||
@ -1516,12 +1563,7 @@ nsresult nsHostResolver::NameLookup(nsHostRecord* rec) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (rec->mTrrServer.IsEmpty()) {
|
||||
rec->mEffectiveTRRMode =
|
||||
EffectiveTRRMode(rec->host, Mode(), rec->TRRMode());
|
||||
} else {
|
||||
rec->mEffectiveTRRMode = nsIRequest::TRR_ONLY_MODE;
|
||||
}
|
||||
ComputeEffectiveTRRMode(rec);
|
||||
|
||||
if (rec->IsAddrRecord()) {
|
||||
RefPtr<AddrHostRecord> addrRec = do_QueryObject(rec);
|
||||
@ -1538,9 +1580,7 @@ nsresult nsHostResolver::NameLookup(nsHostRecord* rec) {
|
||||
|
||||
if (!rec->mTrrServer.IsEmpty()) {
|
||||
LOG(("NameLookup: %s use trr:%s", rec->host.get(), rec->mTrrServer.get()));
|
||||
if (gTRRService->IsExcludedFromTRR(rec->host) ||
|
||||
(gTRRService->SkipTRRWhenParentalControlEnabled() &&
|
||||
gTRRService->ParentalControlEnabled())) {
|
||||
if (rec->mEffectiveTRRMode != nsIRequest::TRR_ONLY_MODE) {
|
||||
return NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
@ -1813,7 +1853,7 @@ void nsHostResolver::AddToEvictionQ(nsHostRecord* rec) {
|
||||
// returns LOOKUP_RESOLVEAGAIN, but only if 'status' is not NS_ERROR_ABORT.
|
||||
nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
|
||||
nsHostRecord* rec, nsresult status, AddrInfo* aNewRRSet, bool pb,
|
||||
const nsACString& aOriginsuffix) {
|
||||
const nsACString& aOriginsuffix, nsHostRecord::TRRSkippedReason aReason) {
|
||||
MutexAutoLock lock(mLock);
|
||||
MOZ_ASSERT(rec);
|
||||
MOZ_ASSERT(rec->pb == pb);
|
||||
@ -1846,11 +1886,13 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
|
||||
MOZ_ASSERT(TRROutstanding());
|
||||
if (newRRSet->IsTRR() == TRRTYPE_A) {
|
||||
MOZ_ASSERT(addrRec->mTrrA);
|
||||
rec->mTRRAFailReason = aReason;
|
||||
addrRec->mTrrA = nullptr;
|
||||
addrRec->mTrrAUsed =
|
||||
NS_SUCCEEDED(status) ? AddrHostRecord::OK : AddrHostRecord::FAILED;
|
||||
} else if (newRRSet->IsTRR() == TRRTYPE_AAAA) {
|
||||
MOZ_ASSERT(addrRec->mTrrAAAA);
|
||||
rec->mTRRAAAAFailReason = aReason;
|
||||
addrRec->mTrrAAAA = nullptr;
|
||||
addrRec->mTrrAAAAUsed =
|
||||
NS_SUCCEEDED(status) ? AddrHostRecord::OK : AddrHostRecord::FAILED;
|
||||
@ -1930,6 +1972,19 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
|
||||
// no TRR success
|
||||
newRRSet = nullptr;
|
||||
status = NS_ERROR_UNKNOWN_HOST;
|
||||
|
||||
// At least one of them was a failure. If the IPv4 response has a
|
||||
// recorded reason, we use that (we also care about ipv4 more).
|
||||
// Otherwise pick the other one.
|
||||
if (rec->mTRRAFailReason != nsHostRecord::TRR_UNSET) {
|
||||
addrRec->RecordReason(rec->mTRRAFailReason);
|
||||
} else {
|
||||
MOZ_ASSERT(rec->mTRRAAAAFailReason != nsHostRecord::TRR_UNSET);
|
||||
addrRec->RecordReason(rec->mTRRAAAAFailReason);
|
||||
}
|
||||
} else {
|
||||
// At least one TRR request succeeded. We mark the response OK.
|
||||
addrRec->RecordReason(nsHostRecord::TRR_OK);
|
||||
}
|
||||
|
||||
if (!addrRec->mTRRSuccess &&
|
||||
@ -2238,8 +2293,9 @@ void nsHostResolver::ThreadFunc() {
|
||||
LOG1(("DNS lookup thread - lookup completed for host [%s]: %s.\n",
|
||||
rec->host.get(), ai ? "success" : "failure: unknown host"));
|
||||
|
||||
if (LOOKUP_RESOLVEAGAIN ==
|
||||
CompleteLookup(rec, status, ai, rec->pb, rec->originSuffix)) {
|
||||
if (LOOKUP_RESOLVEAGAIN == CompleteLookup(rec, status, ai, rec->pb,
|
||||
rec->originSuffix,
|
||||
rec->mTRRTRRSkippedReason)) {
|
||||
// leave 'rec' assigned and loop to make a renewed host resolve
|
||||
LOG(("DNS lookup thread - Re-resolving host [%s].\n", rec->host.get()));
|
||||
} else {
|
||||
|
@ -89,6 +89,46 @@ class nsHostRecord : public mozilla::LinkedListElement<RefPtr<nsHostRecord>>,
|
||||
// Returns the TRR mode encoded by the flags
|
||||
nsIRequest::TRRMode TRRMode();
|
||||
|
||||
// IMPORTANT: when adding new values, always add them to the end, otherwise
|
||||
// it will mess up telemetry.
|
||||
enum TRRSkippedReason : uint32_t {
|
||||
TRR_UNSET = 0,
|
||||
TRR_OK = 1, // Only set when we actually got a positive TRR result
|
||||
TRR_NO_GSERVICE = 2, // no gService
|
||||
TRR_PARENTAL_CONTROL = 3, // parental control is on
|
||||
TRR_OFF_EXPLICIT = 4, // user has set mode5
|
||||
TRR_REQ_MODE_DISABLED = 5, // request has disabled flags set
|
||||
TRR_MODE_NOT_ENABLED = 6, // mode0
|
||||
TRR_FAILED = 7, // unknown failure
|
||||
TRR_MODE_UNHANDLED_DEFAULT = 8, // Unhandled case in ComputeEffectiveMode
|
||||
TRR_MODE_UNHANDLED_DISABLED = 9, // Unhandled case in ComputeEffectiveMode
|
||||
TRR_DISABLED_FLAG = 10, // the DISABLE_TRR flag was set
|
||||
TRR_TIMEOUT = 11, // the TRR channel timed out
|
||||
TRR_CHANNEL_DNS_FAIL = 12, // DoH server name failed to resolve
|
||||
TRR_IS_OFFLINE = 13, // The browser is offline or lacks connectivity
|
||||
TRR_NOT_CONFIRMED = 14, // TRR confirmation is not done yet
|
||||
TRR_DID_NOT_MAKE_QUERY = 15, // TrrLookup exited without doing a TRR query
|
||||
TRR_UNKNOWN_CHANNEL_FAILURE = 16, // unknown channel failure reason
|
||||
TRR_HOST_BLOCKED_TEMPORARY = 17, // host blacklisted
|
||||
TRR_SEND_FAILED = 18, // The call to TRR::SendHTTPRequest failed
|
||||
TRR_NET_RESET = 19, // NS_ERROR_NET_RESET
|
||||
TRR_NET_TIMEOUT = 20, // NS_ERROR_NET_TIMEOUT
|
||||
TRR_NET_REFUSED = 21, // NS_ERROR_CONNECTION_REFUSED
|
||||
TRR_NET_INTERRUPT = 22, // NS_ERROR_NET_INTERRUPT
|
||||
TRR_NET_INADEQ_SEQURITY = 23, // NS_ERROR_NET_INADEQUATE_SECURITY
|
||||
TRR_NO_ANSWERS = 24, // TRR returned no answers
|
||||
TRR_DECODE_FAILED = 25, // DohDecode failed
|
||||
TRR_EXCLUDED = 26, // ExcludedFromTRR
|
||||
TRR_SERVER_RESPONSE_ERR = 27, // Server responded with non-200 code
|
||||
};
|
||||
|
||||
// Records the first reason that caused TRR to be skipped or to fail.
|
||||
void RecordReason(TRRSkippedReason reason) {
|
||||
if (mTRRTRRSkippedReason == TRR_UNSET) {
|
||||
mTRRTRRSkippedReason = reason;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class nsHostResolver;
|
||||
friend class mozilla::net::TRR;
|
||||
@ -152,6 +192,10 @@ class nsHostRecord : public mozilla::LinkedListElement<RefPtr<nsHostRecord>>,
|
||||
// parental controls are on, domain matches exclusion list, etc.
|
||||
nsIRequest::TRRMode mEffectiveTRRMode;
|
||||
|
||||
TRRSkippedReason mTRRTRRSkippedReason = TRR_UNSET;
|
||||
TRRSkippedReason mTRRAFailReason = TRR_UNSET;
|
||||
TRRSkippedReason mTRRAAAAFailReason = TRR_UNSET;
|
||||
|
||||
uint16_t mResolving; // counter of outstanding resolving calls
|
||||
|
||||
uint8_t negative : 1; /* True if this record is a cache of a failed
|
||||
@ -382,9 +426,10 @@ class AHostResolver {
|
||||
LOOKUP_RESOLVEAGAIN,
|
||||
};
|
||||
|
||||
virtual LookupStatus CompleteLookup(nsHostRecord*, nsresult,
|
||||
mozilla::net::AddrInfo*, bool pb,
|
||||
const nsACString& aOriginsuffix) = 0;
|
||||
virtual LookupStatus CompleteLookup(
|
||||
nsHostRecord*, nsresult, mozilla::net::AddrInfo*, bool pb,
|
||||
const nsACString& aOriginsuffix,
|
||||
nsHostRecord::TRRSkippedReason aReason) = 0;
|
||||
virtual LookupStatus CompleteLookupByType(
|
||||
nsHostRecord*, nsresult, mozilla::net::TypeRecordResultType& aResult,
|
||||
uint32_t aTtl, bool pb) = 0;
|
||||
@ -499,8 +544,8 @@ class nsHostResolver : public nsISupports, public AHostResolver {
|
||||
void FlushCache(bool aTrrToo);
|
||||
|
||||
LookupStatus CompleteLookup(nsHostRecord*, nsresult, mozilla::net::AddrInfo*,
|
||||
bool pb,
|
||||
const nsACString& aOriginsuffix) override;
|
||||
bool pb, const nsACString& aOriginsuffix,
|
||||
nsHostRecord::TRRSkippedReason aReason) override;
|
||||
LookupStatus CompleteLookupByType(nsHostRecord*, nsresult,
|
||||
mozilla::net::TypeRecordResultType& aResult,
|
||||
uint32_t aTtl, bool pb) override;
|
||||
@ -510,6 +555,7 @@ class nsHostResolver : public nsISupports, public AHostResolver {
|
||||
nsHostRecord** result) override;
|
||||
nsresult TrrLookup_unlocked(nsHostRecord*,
|
||||
mozilla::net::TRR* pushedTRR = nullptr) override;
|
||||
static mozilla::net::ResolverMode Mode();
|
||||
|
||||
private:
|
||||
explicit nsHostResolver(uint32_t maxCacheEntries,
|
||||
@ -520,7 +566,7 @@ class nsHostResolver : public nsISupports, public AHostResolver {
|
||||
nsresult Init();
|
||||
// In debug builds it asserts that the element is in the list.
|
||||
void AssertOnQ(nsHostRecord*, mozilla::LinkedList<RefPtr<nsHostRecord>>&);
|
||||
mozilla::net::ResolverMode Mode();
|
||||
static void ComputeEffectiveTRRMode(nsHostRecord* aRec);
|
||||
nsresult NativeLookup(nsHostRecord*);
|
||||
nsresult TrrLookup(nsHostRecord*, mozilla::net::TRR* pushedTRR = nullptr);
|
||||
|
||||
|
@ -4008,6 +4008,28 @@
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "DNS: success distribution when both native and TRR were used"
|
||||
},
|
||||
"TRR_SKIP_REASON_TRR_FIRST": {
|
||||
"record_in_processes": ["main", "socket"],
|
||||
"products": ["firefox", "fennec"],
|
||||
"alert_emails": ["necko@mozilla.com", "vgosu@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 50,
|
||||
"bug_numbers": [1649143],
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "When in TRR-first mode, it lists the reason we may have skipped TRR"
|
||||
},
|
||||
"TRR_SKIP_REASON_DNS_WORKED": {
|
||||
"record_in_processes": ["main", "socket"],
|
||||
"products": ["firefox", "fennec"],
|
||||
"alert_emails": ["necko@mozilla.com", "vgosu@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 50,
|
||||
"bug_numbers": [1649143],
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "When in TRR-first mode if DNS succeeded, it lists the reason we may have skipped TRR"
|
||||
},
|
||||
"DNS_TRR_FIRST3": {
|
||||
"record_in_processes": ["main"],
|
||||
"products": ["firefox", "fennec"],
|
||||
|
Loading…
Reference in New Issue
Block a user