mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1673590 - Move TRR handling logic from nsHostResolver to TRRQuery r=necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D94822
This commit is contained in:
parent
ffe82f7865
commit
6b00235dd5
@ -1371,7 +1371,6 @@ void TRR::SaveAdditionalRecords(
|
||||
hostRecord->mEffectiveTRRMode = mRec->mEffectiveTRRMode;
|
||||
RefPtr<AddrHostRecord> addrRec = do_QueryObject(hostRecord);
|
||||
addrRec->mTrrStart = TimeStamp::Now();
|
||||
addrRec->mTrrA = this; // Hack!
|
||||
LOG(("Completing lookup for additional: %s", nsCString(iter.Key()).get()));
|
||||
(void)mHostResolver->CompleteLookup(hostRecord, NS_OK, ai, mPB,
|
||||
mOriginSuffix, AddrHostRecord::TRR_OK);
|
||||
@ -1510,7 +1509,6 @@ void TRR::StoreIPHintAsDNSRecord(const struct SVCB& aSVCBRecord) {
|
||||
hostRecord->mEffectiveTRRMode = mRec->mEffectiveTRRMode;
|
||||
RefPtr<AddrHostRecord> addrRec = do_QueryObject(hostRecord);
|
||||
addrRec->mTrrStart = TimeStamp::Now();
|
||||
addrRec->mTrrA = this; // Hack!
|
||||
|
||||
(void)mHostResolver->CompleteLookup(hostRecord, NS_OK, ai, mPB, mOriginSuffix,
|
||||
AddrHostRecord::TRR_OK);
|
||||
|
289
netwerk/dns/TRRQuery.cpp
Normal file
289
netwerk/dns/TRRQuery.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "TRRQuery.h"
|
||||
#include "TRR.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
#undef LOG
|
||||
extern mozilla::LazyLogModule gHostResolverLog;
|
||||
#define LOG(args) MOZ_LOG(gHostResolverLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
static already_AddRefed<AddrInfo> merge_rrset(AddrInfo* rrto,
|
||||
AddrInfo* rrfrom) {
|
||||
MOZ_ASSERT(rrto && rrfrom);
|
||||
// Each of the arguments are all-IPv4 or all-IPv6 hence judging
|
||||
// by the first element. This is true only for TRR resolutions.
|
||||
bool isIPv6 = rrfrom->Addresses().Length() > 0 &&
|
||||
rrfrom->Addresses()[0].raw.family == PR_AF_INET6;
|
||||
|
||||
nsTArray<NetAddr> addresses = rrto->Addresses().Clone();
|
||||
for (const auto& addr : rrfrom->Addresses()) {
|
||||
if (isIPv6) {
|
||||
// rrfrom has IPv6 so it should be first
|
||||
addresses.InsertElementAt(0, addr);
|
||||
} else {
|
||||
addresses.AppendElement(addr);
|
||||
}
|
||||
}
|
||||
auto builder = rrto->Build();
|
||||
builder.SetAddresses(std::move(addresses));
|
||||
return builder.Finish();
|
||||
}
|
||||
|
||||
void TRRQuery::Cancel() {
|
||||
MutexAutoLock trrlock(mTrrLock);
|
||||
if (mTrrA) {
|
||||
mTrrA->Cancel();
|
||||
mTrrA = nullptr;
|
||||
}
|
||||
if (mTrrAAAA) {
|
||||
mTrrAAAA->Cancel();
|
||||
mTrrAAAA = nullptr;
|
||||
}
|
||||
if (mTrrByType) {
|
||||
mTrrByType->Cancel();
|
||||
mTrrByType = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult TRRQuery::DispatchLookup(TRR* pushedTRR) {
|
||||
mTrrStart = TimeStamp::Now();
|
||||
|
||||
RefPtr<AddrHostRecord> addrRec;
|
||||
RefPtr<TypeHostRecord> typeRec;
|
||||
|
||||
if (mRecord->IsAddrRecord()) {
|
||||
addrRec = do_QueryObject(mRecord);
|
||||
MOZ_ASSERT(addrRec);
|
||||
} else {
|
||||
typeRec = do_QueryObject(mRecord);
|
||||
MOZ_ASSERT(typeRec);
|
||||
}
|
||||
|
||||
mTrrStart = TimeStamp::Now();
|
||||
bool madeQuery = false;
|
||||
|
||||
if (addrRec) {
|
||||
mTrrAUsed = INIT;
|
||||
mTrrAAAAUsed = INIT;
|
||||
|
||||
// If asking for AF_UNSPEC, issue both A and AAAA.
|
||||
// If asking for AF_INET6 or AF_INET, do only that single type
|
||||
enum TrrType rectype = (mRecord->af == AF_INET6) ? TRRTYPE_AAAA : TRRTYPE_A;
|
||||
|
||||
if (pushedTRR) {
|
||||
rectype = pushedTRR->Type();
|
||||
}
|
||||
bool sendAgain;
|
||||
|
||||
do {
|
||||
sendAgain = false;
|
||||
if ((TRRTYPE_AAAA == rectype) && gTRRService &&
|
||||
(gTRRService->DisableIPv6() ||
|
||||
(StaticPrefs::network_trr_skip_AAAA_when_not_supported() &&
|
||||
mHostResolver->GetNCS() &&
|
||||
mHostResolver->GetNCS()->GetIPv6() ==
|
||||
nsINetworkConnectivityService::NOT_AVAILABLE))) {
|
||||
break;
|
||||
}
|
||||
LOG(("TRR Resolve %s type %d\n", addrRec->host.get(), (int)rectype));
|
||||
RefPtr<TRR> trr;
|
||||
trr = pushedTRR ? pushedTRR : new TRR(this, mRecord, rectype);
|
||||
if (pushedTRR || NS_SUCCEEDED(gTRRService->DispatchTRRRequest(trr))) {
|
||||
MutexAutoLock trrlock(mTrrLock);
|
||||
if (rectype == TRRTYPE_A) {
|
||||
MOZ_ASSERT(!mTrrA);
|
||||
mTrrA = trr;
|
||||
mTrrAUsed = STARTED;
|
||||
} else if (rectype == TRRTYPE_AAAA) {
|
||||
MOZ_ASSERT(!mTrrAAAA);
|
||||
mTrrAAAA = trr;
|
||||
mTrrAAAAUsed = STARTED;
|
||||
} else {
|
||||
LOG(("TrrLookup called with bad type set: %d\n", rectype));
|
||||
MOZ_ASSERT(0);
|
||||
}
|
||||
madeQuery = true;
|
||||
if (!pushedTRR && (mRecord->af == AF_UNSPEC) &&
|
||||
(rectype == TRRTYPE_A)) {
|
||||
rectype = TRRTYPE_AAAA;
|
||||
sendAgain = true;
|
||||
}
|
||||
}
|
||||
} while (sendAgain);
|
||||
} else {
|
||||
typeRec->mStart = TimeStamp::Now();
|
||||
enum TrrType rectype;
|
||||
|
||||
// XXX this could use a more extensible approach.
|
||||
if (mRecord->type == nsIDNSService::RESOLVE_TYPE_TXT) {
|
||||
rectype = TRRTYPE_TXT;
|
||||
} else if (mRecord->type == nsIDNSService::RESOLVE_TYPE_HTTPSSVC) {
|
||||
rectype = TRRTYPE_HTTPSSVC;
|
||||
} else if (pushedTRR) {
|
||||
rectype = pushedTRR->Type();
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Not an expected request type");
|
||||
return NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
LOG(("TRR Resolve %s type %d\n", typeRec->host.get(), (int)rectype));
|
||||
RefPtr<TRR> trr;
|
||||
trr = pushedTRR ? pushedTRR : new TRR(this, mRecord, rectype);
|
||||
RefPtr<TRR> trrRequest = trr;
|
||||
if (pushedTRR || NS_SUCCEEDED(gTRRService->DispatchTRRRequest(trr))) {
|
||||
MutexAutoLock trrlock(mTrrLock);
|
||||
MOZ_ASSERT(!mTrrByType);
|
||||
mTrrByType = trr;
|
||||
madeQuery = true;
|
||||
}
|
||||
}
|
||||
|
||||
return madeQuery ? NS_OK : NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
AHostResolver::LookupStatus TRRQuery::CompleteLookup(
|
||||
nsHostRecord* rec, nsresult status, AddrInfo* aNewRRSet, bool pb,
|
||||
const nsACString& aOriginsuffix, nsHostRecord::TRRSkippedReason aReason) {
|
||||
if (rec != mRecord) {
|
||||
return mHostResolver->CompleteLookup(rec, status, aNewRRSet, pb,
|
||||
aOriginsuffix, aReason);
|
||||
}
|
||||
|
||||
RefPtr<AddrInfo> newRRSet(aNewRRSet);
|
||||
bool pendingARequest = false;
|
||||
bool pendingAAAARequest = false;
|
||||
{
|
||||
MutexAutoLock trrlock(mTrrLock);
|
||||
if (newRRSet->IsTRR() == TRRTYPE_A) {
|
||||
MOZ_ASSERT(mTrrA);
|
||||
mTRRAFailReason = aReason;
|
||||
mTrrA = nullptr;
|
||||
mTrrAUsed = NS_SUCCEEDED(status) ? OK : FAILED;
|
||||
} else if (newRRSet->IsTRR() == TRRTYPE_AAAA) {
|
||||
MOZ_ASSERT(mTrrAAAA);
|
||||
mTRRAAAAFailReason = aReason;
|
||||
mTrrAAAA = nullptr;
|
||||
mTrrAAAAUsed = NS_SUCCEEDED(status) ? OK : FAILED;
|
||||
} else {
|
||||
MOZ_ASSERT(0);
|
||||
}
|
||||
if (mTrrA) {
|
||||
pendingARequest = true;
|
||||
}
|
||||
if (mTrrAAAA) {
|
||||
pendingAAAARequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(status)) {
|
||||
mTRRSuccess++;
|
||||
if (mTRRSuccess == 1) {
|
||||
// Store the duration on first succesful TRR response. We
|
||||
// don't know that there will be a second response nor can we
|
||||
// tell which of two has useful data.
|
||||
mTrrDuration = TimeStamp::Now() - mTrrStart;
|
||||
}
|
||||
}
|
||||
|
||||
if (pendingARequest ||
|
||||
pendingAAAARequest) { // There are other outstanding requests
|
||||
mFirstTRRresult = status;
|
||||
if (NS_FAILED(status)) {
|
||||
return LOOKUP_OK; // wait for outstanding
|
||||
}
|
||||
|
||||
// There's another TRR complete pending. Wait for it and keep
|
||||
// this RRset around until then.
|
||||
MOZ_ASSERT(!mFirstTRR && newRRSet);
|
||||
mFirstTRR.swap(newRRSet); // autoPtr.swap()
|
||||
MOZ_ASSERT(mFirstTRR && !newRRSet);
|
||||
|
||||
if (StaticPrefs::network_trr_wait_for_A_and_AAAA()) {
|
||||
LOG(("CompleteLookup: waiting for all responses!\n"));
|
||||
return LOOKUP_OK;
|
||||
}
|
||||
|
||||
if (pendingARequest && !StaticPrefs::network_trr_early_AAAA()) {
|
||||
// This is an early AAAA with a pending A response. Allowed
|
||||
// only by pref.
|
||||
LOG(("CompleteLookup: avoiding early use of TRR AAAA!\n"));
|
||||
return LOOKUP_OK;
|
||||
}
|
||||
|
||||
// we can do some callbacks with this partial result which requires
|
||||
// a deep copy
|
||||
newRRSet = mFirstTRR;
|
||||
|
||||
// Increment mResolving so we wait for the next resolve too.
|
||||
rec->mResolving++;
|
||||
} else {
|
||||
// no more outstanding TRRs
|
||||
// If mFirstTRR is set, merge those addresses into current set!
|
||||
if (mFirstTRR) {
|
||||
if (NS_SUCCEEDED(status)) {
|
||||
LOG(("Merging responses"));
|
||||
newRRSet = merge_rrset(newRRSet, mFirstTRR);
|
||||
} else {
|
||||
LOG(("Will use previous response"));
|
||||
newRRSet.swap(mFirstTRR); // transfers
|
||||
// We must use the status of the first response, otherwise we'll
|
||||
// pass an error result to the consumers.
|
||||
status = mFirstTRRresult;
|
||||
}
|
||||
mFirstTRR = nullptr;
|
||||
} else {
|
||||
if (NS_FAILED(status) && status != NS_ERROR_DEFINITIVE_UNKNOWN_HOST &&
|
||||
mFirstTRRresult == NS_ERROR_DEFINITIVE_UNKNOWN_HOST) {
|
||||
status = NS_ERROR_DEFINITIVE_UNKNOWN_HOST;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTRRSuccess && mHostResolver->GetNCS() &&
|
||||
(mHostResolver->GetNCS()->GetNAT64() ==
|
||||
nsINetworkConnectivityService::OK) &&
|
||||
newRRSet) {
|
||||
newRRSet = mHostResolver->GetNCS()->MapNAT64IPs(newRRSet);
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrrAUsed == OK) {
|
||||
AccumulateCategoricalKeyed(
|
||||
TRRService::AutoDetectedKey(),
|
||||
Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrAOK);
|
||||
} else if (mTrrAUsed == FAILED) {
|
||||
AccumulateCategoricalKeyed(
|
||||
TRRService::AutoDetectedKey(),
|
||||
Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrAFail);
|
||||
}
|
||||
|
||||
if (mTrrAAAAUsed == OK) {
|
||||
AccumulateCategoricalKeyed(
|
||||
TRRService::AutoDetectedKey(),
|
||||
Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrAAAAOK);
|
||||
} else if (mTrrAAAAUsed == FAILED) {
|
||||
AccumulateCategoricalKeyed(
|
||||
TRRService::AutoDetectedKey(),
|
||||
Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrAAAAFail);
|
||||
}
|
||||
|
||||
return mHostResolver->CompleteLookup(rec, status, newRRSet, pb, aOriginsuffix,
|
||||
aReason);
|
||||
}
|
||||
|
||||
AHostResolver::LookupStatus TRRQuery::CompleteLookupByType(
|
||||
nsHostRecord* rec, nsresult status,
|
||||
mozilla::net::TypeRecordResultType& aResult, uint32_t aTtl, bool pb) {
|
||||
if (rec == mRecord) {
|
||||
MutexAutoLock trrlock(mTrrLock);
|
||||
mTrrByType = nullptr;
|
||||
}
|
||||
return mHostResolver->CompleteLookupByType(rec, status, aResult, aTtl, pb);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
90
netwerk/dns/TRRQuery.h
Normal file
90
netwerk/dns/TRRQuery.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_net_TRRQuery_h
|
||||
#define mozilla_net_TRRQuery_h
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class TRRQuery : public AHostResolver {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TRRQuery, override)
|
||||
|
||||
public:
|
||||
TRRQuery(nsHostResolver* aHostResolver, nsHostRecord* aHostRecord)
|
||||
: mHostResolver(aHostResolver),
|
||||
mRecord(aHostRecord),
|
||||
mTrrLock("TRRQuery.mTrrLock") {}
|
||||
|
||||
nsresult DispatchLookup(TRR* pushedTRR = nullptr);
|
||||
|
||||
void Cancel();
|
||||
|
||||
enum TRRState { INIT, STARTED, OK, FAILED };
|
||||
TRRState mTrrAUsed = INIT;
|
||||
TRRState mTrrAAAAUsed = INIT;
|
||||
|
||||
AddrHostRecord::TRRSkippedReason mTRRAFailReason = AddrHostRecord::TRR_UNSET;
|
||||
AddrHostRecord::TRRSkippedReason mTRRAAAAFailReason =
|
||||
AddrHostRecord::TRR_UNSET;
|
||||
|
||||
virtual LookupStatus CompleteLookup(
|
||||
nsHostRecord*, nsresult, mozilla::net::AddrInfo*, bool pb,
|
||||
const nsACString& aOriginsuffix,
|
||||
nsHostRecord::TRRSkippedReason aReason) override;
|
||||
virtual LookupStatus CompleteLookupByType(
|
||||
nsHostRecord*, nsresult, mozilla::net::TypeRecordResultType& aResult,
|
||||
uint32_t aTtl, bool pb) override;
|
||||
virtual nsresult GetHostRecord(const nsACString& host,
|
||||
const nsACString& aTrrServer, uint16_t type,
|
||||
uint16_t flags, uint16_t af, bool pb,
|
||||
const nsCString& originSuffix,
|
||||
nsHostRecord** result) override {
|
||||
if (!mHostResolver) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return mHostResolver->GetHostRecord(host, aTrrServer, type, flags, af, pb,
|
||||
originSuffix, result);
|
||||
}
|
||||
virtual nsresult TrrLookup_unlocked(
|
||||
nsHostRecord* rec, mozilla::net::TRR* pushedTRR = nullptr) override {
|
||||
if (!mHostResolver) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return mHostResolver->TrrLookup_unlocked(rec, pushedTRR);
|
||||
}
|
||||
virtual void MaybeRenewHostRecord(nsHostRecord* aRec) override {
|
||||
if (!mHostResolver) {
|
||||
return;
|
||||
}
|
||||
mHostResolver->MaybeRenewHostRecord(aRec);
|
||||
}
|
||||
|
||||
mozilla::TimeDuration Duration() { return mTrrDuration; }
|
||||
|
||||
private:
|
||||
~TRRQuery() = default;
|
||||
RefPtr<nsHostResolver> mHostResolver;
|
||||
RefPtr<nsHostRecord> mRecord;
|
||||
|
||||
Mutex mTrrLock; // lock when accessing the mTrrA[AAA] pointers
|
||||
RefPtr<mozilla::net::TRR> mTrrA;
|
||||
RefPtr<mozilla::net::TRR> mTrrAAAA;
|
||||
RefPtr<mozilla::net::TRR> mTrrByType;
|
||||
|
||||
uint8_t mTRRSuccess = 0; // number of successful TRR responses
|
||||
|
||||
mozilla::TimeDuration mTrrDuration;
|
||||
mozilla::TimeStamp mTrrStart;
|
||||
|
||||
RefPtr<mozilla::net::AddrInfo> mFirstTRR; // partial TRR storage
|
||||
nsresult mFirstTRRresult = NS_OK;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_TRRQuery_h
|
@ -20,6 +20,9 @@
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
static const char kRolloutURIPref[] = "doh-rollout.uri";
|
||||
static const char kRolloutModePref[] = "doh-rollout.mode";
|
||||
|
||||
static const char* gTRRUriCallbackPrefs[] = {
|
||||
"network.trr.uri", "network.trr.mode", kRolloutURIPref, kRolloutModePref,
|
||||
nullptr,
|
||||
|
@ -72,6 +72,7 @@ UNIFIED_SOURCES += [
|
||||
"nsIDNService.cpp",
|
||||
"punycode.c",
|
||||
"TRR.cpp",
|
||||
"TRRQuery.cpp",
|
||||
"TRRService.cpp",
|
||||
"TRRServiceBase.cpp",
|
||||
"TRRServiceChild.cpp",
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "GetAddrInfo.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "TRR.h"
|
||||
#include "TRRQuery.h"
|
||||
#include "TRRService.h"
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
@ -196,12 +197,25 @@ NS_IMPL_ISUPPORTS0(nsHostRecord)
|
||||
nsHostRecord::nsHostRecord(const nsHostKey& key)
|
||||
: nsHostKey(key),
|
||||
mEffectiveTRRMode(nsIRequest::TRR_DEFAULT_MODE),
|
||||
mTRRQuery("nsHostRecord.mTRRQuery"),
|
||||
mResolving(0),
|
||||
negative(false),
|
||||
mDoomed(false) {}
|
||||
|
||||
void nsHostRecord::Invalidate() { mDoomed = true; }
|
||||
|
||||
void nsHostRecord::Cancel() {
|
||||
RefPtr<TRRQuery> query;
|
||||
{
|
||||
auto lock = mTRRQuery.Lock();
|
||||
query.swap(lock.ref());
|
||||
}
|
||||
|
||||
if (query) {
|
||||
query->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
nsHostRecord::ExpirationStatus nsHostRecord::CheckExpiration(
|
||||
const mozilla::TimeStamp& now) const {
|
||||
if (!mGraceStart.IsNull() && now >= mGraceStart && !mValidEnd.IsNull() &&
|
||||
@ -279,7 +293,6 @@ AddrHostRecord::AddrHostRecord(const nsHostKey& key)
|
||||
addr_info_gencnt(0),
|
||||
addr_info(nullptr),
|
||||
addr(nullptr),
|
||||
mFirstTRRresult(NS_OK),
|
||||
mTRRUsed(false),
|
||||
mTRRSuccess(0),
|
||||
mNativeSuccess(0),
|
||||
@ -287,12 +300,8 @@ AddrHostRecord::AddrHostRecord(const nsHostKey& key)
|
||||
mNativeUsed(false),
|
||||
onQueue(false),
|
||||
usingAnyThread(false),
|
||||
mDidCallbacks(false),
|
||||
mGetTtl(false),
|
||||
mResolveAgain(false),
|
||||
mTrrAUsed(INIT),
|
||||
mTrrAAAAUsed(INIT),
|
||||
mTrrLock("AddrHostRecord.mTrrLock") {}
|
||||
mResolveAgain(false) {}
|
||||
|
||||
AddrHostRecord::~AddrHostRecord() {
|
||||
mCallbacks.clear();
|
||||
@ -371,18 +380,6 @@ bool AddrHostRecord::HasUsableResultInternal() const {
|
||||
return addr_info || addr;
|
||||
}
|
||||
|
||||
void AddrHostRecord::Cancel() {
|
||||
MutexAutoLock trrlock(mTrrLock);
|
||||
if (mTrrA) {
|
||||
mTrrA->Cancel();
|
||||
mTrrA = nullptr;
|
||||
}
|
||||
if (mTrrAAAA) {
|
||||
mTrrAAAA->Cancel();
|
||||
mTrrAAAA = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if the entry can be removed, or false if it should be left.
|
||||
// Sets mResolveAgain true for entries being resolved right now.
|
||||
bool AddrHostRecord::RemoveOrRefresh(bool aTrrToo) {
|
||||
@ -428,26 +425,6 @@ void AddrHostRecord::ResolveComplete() {
|
||||
TRRService::AutoDetectedKey(),
|
||||
mTRRSuccess ? Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrOK
|
||||
: Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrFail);
|
||||
|
||||
if (mTrrAUsed == OK) {
|
||||
AccumulateCategoricalKeyed(
|
||||
TRRService::AutoDetectedKey(),
|
||||
Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrAOK);
|
||||
} else if (mTrrAUsed == FAILED) {
|
||||
AccumulateCategoricalKeyed(
|
||||
TRRService::AutoDetectedKey(),
|
||||
Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrAFail);
|
||||
}
|
||||
|
||||
if (mTrrAAAAUsed == OK) {
|
||||
AccumulateCategoricalKeyed(
|
||||
TRRService::AutoDetectedKey(),
|
||||
Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrAAAAOK);
|
||||
} else if (mTrrAAAAUsed == FAILED) {
|
||||
AccumulateCategoricalKeyed(
|
||||
TRRService::AutoDetectedKey(),
|
||||
Telemetry::LABELS_DNS_LOOKUP_DISPOSITION2::trrAAAAFail);
|
||||
}
|
||||
}
|
||||
|
||||
if (nsHostResolver::Mode() == MODE_TRRFIRST) {
|
||||
@ -523,7 +500,6 @@ NS_IMPL_ISUPPORTS_INHERITED(TypeHostRecord, nsHostRecord, TypeHostRecord,
|
||||
TypeHostRecord::TypeHostRecord(const nsHostKey& key)
|
||||
: nsHostRecord(key),
|
||||
DNSHTTPSSVCRecordBase(key.host),
|
||||
mTrrLock("TypeHostRecord.mTrrLock"),
|
||||
mResultsLock("TypeHostRecord.mResultsLock"),
|
||||
mAllRecordsExcluded(false) {}
|
||||
|
||||
@ -567,13 +543,6 @@ size_t TypeHostRecord::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const {
|
||||
return n;
|
||||
}
|
||||
|
||||
void TypeHostRecord::Cancel() {
|
||||
if (mTrr) {
|
||||
mTrr->Cancel();
|
||||
mTrr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t TypeHostRecord::GetType() {
|
||||
MutexAutoLock lock(mResultsLock);
|
||||
|
||||
@ -1254,16 +1223,6 @@ nsresult nsHostResolver::ResolveHost(const nsACString& aHost,
|
||||
host.get(), callback.get()));
|
||||
}
|
||||
}
|
||||
|
||||
} else if (addrRec && addrRec->mDidCallbacks) {
|
||||
// This is only for A/AAAA query.
|
||||
// record is still pending more (TRR) data; make the callback
|
||||
// at once
|
||||
result = rec;
|
||||
// make it count as a hit
|
||||
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2, METHOD_HIT);
|
||||
|
||||
LOG((" Host [%s] re-using early TRR resolve data\n", host.get()));
|
||||
} else {
|
||||
LOG(
|
||||
(" Host [%s] is being resolved. Appending callback "
|
||||
@ -1374,9 +1333,6 @@ nsresult nsHostResolver::ConditionallyCreateThread(nsHostRecord* rec) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// make sure the mTrrLock is held when this is used!
|
||||
#define TRROutstanding() ((addrRec->mTrrA || addrRec->mTrrAAAA))
|
||||
|
||||
nsresult nsHostResolver::TrrLookup_unlocked(nsHostRecord* rec, TRR* pushedTRR) {
|
||||
MutexAutoLock lock(mLock);
|
||||
return TrrLookup(rec, pushedTRR);
|
||||
@ -1420,12 +1376,6 @@ nsresult nsHostResolver::TrrLookup(nsHostRecord* aRec, TRR* pushedTRR) {
|
||||
MOZ_ASSERT(typeRec);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (rec->IsAddrRecord()) {
|
||||
MutexAutoLock trrlock(addrRec->mTrrLock);
|
||||
MOZ_ASSERT(!TRROutstanding());
|
||||
}
|
||||
#endif
|
||||
MOZ_ASSERT(!rec->mResolving);
|
||||
|
||||
nsIRequest::TRRMode reqMode = rec->mEffectiveTRRMode;
|
||||
@ -1438,89 +1388,21 @@ nsresult nsHostResolver::TrrLookup(nsHostRecord* aRec, TRR* pushedTRR) {
|
||||
|
||||
MaybeRenewHostRecordLocked(rec);
|
||||
|
||||
bool madeQuery = false;
|
||||
|
||||
if (addrRec) {
|
||||
addrRec->mTRRSuccess = 0; // bump for each successful TRR response
|
||||
addrRec->mTrrStart = TimeStamp::Now();
|
||||
addrRec->mTrrAUsed = AddrHostRecord::INIT;
|
||||
addrRec->mTrrAAAAUsed = AddrHostRecord::INIT;
|
||||
|
||||
// If asking for AF_UNSPEC, issue both A and AAAA.
|
||||
// If asking for AF_INET6 or AF_INET, do only that single type
|
||||
enum TrrType rectype = (rec->af == AF_INET6) ? TRRTYPE_AAAA : TRRTYPE_A;
|
||||
|
||||
if (pushedTRR) {
|
||||
rectype = pushedTRR->Type();
|
||||
}
|
||||
bool sendAgain;
|
||||
|
||||
do {
|
||||
sendAgain = false;
|
||||
if ((TRRTYPE_AAAA == rectype) && gTRRService &&
|
||||
(gTRRService->DisableIPv6() ||
|
||||
(StaticPrefs::network_trr_skip_AAAA_when_not_supported() && mNCS &&
|
||||
mNCS->GetIPv6() == nsINetworkConnectivityService::NOT_AVAILABLE))) {
|
||||
break;
|
||||
}
|
||||
LOG(("TRR Resolve %s type %d\n", addrRec->host.get(), (int)rectype));
|
||||
RefPtr<TRR> trr;
|
||||
MutexAutoLock trrlock(addrRec->mTrrLock);
|
||||
trr = pushedTRR ? pushedTRR : new TRR(this, rec, rectype);
|
||||
if (pushedTRR || NS_SUCCEEDED(gTRRService->DispatchTRRRequest(trr))) {
|
||||
addrRec->mResolving++;
|
||||
if (rectype == TRRTYPE_A) {
|
||||
MOZ_ASSERT(!addrRec->mTrrA);
|
||||
addrRec->mTrrA = trr;
|
||||
addrRec->mTrrAUsed = AddrHostRecord::STARTED;
|
||||
} else if (rectype == TRRTYPE_AAAA) {
|
||||
MOZ_ASSERT(!addrRec->mTrrAAAA);
|
||||
addrRec->mTrrAAAA = trr;
|
||||
addrRec->mTrrAAAAUsed = AddrHostRecord::STARTED;
|
||||
} else {
|
||||
LOG(("TrrLookup called with bad type set: %d\n", rectype));
|
||||
MOZ_ASSERT(0);
|
||||
}
|
||||
madeQuery = true;
|
||||
if (!pushedTRR && (rec->af == AF_UNSPEC) && (rectype == TRRTYPE_A)) {
|
||||
rectype = TRRTYPE_AAAA;
|
||||
sendAgain = true;
|
||||
}
|
||||
}
|
||||
} while (sendAgain);
|
||||
} else {
|
||||
typeRec->mStart = TimeStamp::Now();
|
||||
enum TrrType rectype;
|
||||
|
||||
// XXX this could use a more extensible approach.
|
||||
if (rec->type == nsIDNSService::RESOLVE_TYPE_TXT) {
|
||||
rectype = TRRTYPE_TXT;
|
||||
} else if (rec->type == nsIDNSService::RESOLVE_TYPE_HTTPSSVC) {
|
||||
rectype = TRRTYPE_HTTPSSVC;
|
||||
} else if (pushedTRR) {
|
||||
rectype = pushedTRR->Type();
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Not an expected request type");
|
||||
return NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
LOG(("TRR Resolve %s type %d\n", typeRec->host.get(), (int)rectype));
|
||||
RefPtr<TRR> trr;
|
||||
MutexAutoLock trrlock(typeRec->mTrrLock);
|
||||
trr = pushedTRR ? pushedTRR : new TRR(this, rec, rectype);
|
||||
RefPtr<TRR> trrRequest = trr;
|
||||
if (pushedTRR || NS_SUCCEEDED(gTRRService->DispatchTRRRequest(trr))) {
|
||||
typeRec->mResolving++;
|
||||
MOZ_ASSERT(!typeRec->mTrr);
|
||||
typeRec->mTrr = trr;
|
||||
madeQuery = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!madeQuery) {
|
||||
RefPtr<TRRQuery> query = new TRRQuery(this, rec);
|
||||
nsresult rv = query->DispatchLookup(pushedTRR);
|
||||
if (NS_FAILED(rv)) {
|
||||
rec->RecordReason(nsHostRecord::TRR_DID_NOT_MAKE_QUERY);
|
||||
return rv;
|
||||
}
|
||||
return madeQuery ? NS_OK : NS_ERROR_UNKNOWN_HOST;
|
||||
|
||||
{
|
||||
auto lock = rec->mTRRQuery.Lock();
|
||||
MOZ_ASSERT(!lock.ref(), "TRR already in progress");
|
||||
lock.ref() = query;
|
||||
}
|
||||
|
||||
rec->mResolving++;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsHostResolver::AssertOnQ(nsHostRecord* rec,
|
||||
@ -1695,10 +1577,6 @@ nsresult nsHostResolver::NameLookup(nsHostRecord* rec) {
|
||||
addrRec->mNativeUsed = false;
|
||||
addrRec->mTRRUsed = false;
|
||||
addrRec->mNativeSuccess = false;
|
||||
addrRec->mTRRSuccess = 0;
|
||||
addrRec->mDidCallbacks = false;
|
||||
addrRec->mTrrAUsed = AddrHostRecord::INIT;
|
||||
addrRec->mTrrAAAAUsed = AddrHostRecord::INIT;
|
||||
}
|
||||
|
||||
if (!rec->mTrrServer.IsEmpty()) {
|
||||
@ -1881,28 +1759,6 @@ void nsHostResolver::PrepareRecordExpirationAddrRecord(
|
||||
lifetime, grace));
|
||||
}
|
||||
|
||||
static already_AddRefed<AddrInfo> merge_rrset(AddrInfo* rrto,
|
||||
AddrInfo* rrfrom) {
|
||||
MOZ_ASSERT(rrto && rrfrom);
|
||||
// Each of the arguments are all-IPv4 or all-IPv6 hence judging
|
||||
// by the first element. This is true only for TRR resolutions.
|
||||
bool isIPv6 = rrfrom->Addresses().Length() > 0 &&
|
||||
rrfrom->Addresses()[0].raw.family == PR_AF_INET6;
|
||||
|
||||
nsTArray<NetAddr> addresses = rrto->Addresses().Clone();
|
||||
for (const auto& addr : rrfrom->Addresses()) {
|
||||
if (isIPv6) {
|
||||
// rrfrom has IPv6 so it should be first
|
||||
addresses.InsertElementAt(0, addr);
|
||||
} else {
|
||||
addresses.AppendElement(addr);
|
||||
}
|
||||
}
|
||||
auto builder = rrto->Build();
|
||||
builder.SetAddresses(std::move(addresses));
|
||||
return builder.Finish();
|
||||
}
|
||||
|
||||
static bool different_rrset(AddrInfo* rrset1, AddrInfo* rrset2) {
|
||||
if (!rrset1 || !rrset2) {
|
||||
return true;
|
||||
@ -1982,8 +1838,12 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
|
||||
MOZ_ASSERT(addrRec);
|
||||
|
||||
RefPtr<AddrInfo> newRRSet(aNewRRSet);
|
||||
MOZ_ASSERT(NS_FAILED(status) || newRRSet->Addresses().Length() > 0);
|
||||
|
||||
bool trrResult = newRRSet && newRRSet->IsTRR();
|
||||
if (NS_FAILED(status)) {
|
||||
newRRSet = nullptr;
|
||||
}
|
||||
|
||||
if (addrRec->mResolveAgain && (status != NS_ERROR_ABORT) && !trrResult) {
|
||||
LOG(("nsHostResolver record %p resolve again due to flushcache\n",
|
||||
@ -1996,140 +1856,49 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
|
||||
addrRec->mResolving--;
|
||||
LOG(("nsHostResolver::CompleteLookup %s %p %X trr=%d stillResolving=%d\n",
|
||||
addrRec->host.get(), aNewRRSet, (unsigned int)status,
|
||||
aNewRRSet ? aNewRRSet->IsTRR() : 0, addrRec->mResolving));
|
||||
aNewRRSet ? aNewRRSet->IsTRR() : 0, int(addrRec->mResolving)));
|
||||
|
||||
if (trrResult) {
|
||||
MutexAutoLock trrlock(addrRec->mTrrLock);
|
||||
LOG(("TRR lookup Complete (%d) %s %s\n", newRRSet->IsTRR(),
|
||||
newRRSet->Hostname().get(), NS_SUCCEEDED(status) ? "OK" : "FAILED"));
|
||||
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;
|
||||
if (NS_FAILED(status) && status != NS_ERROR_UNKNOWN_HOST &&
|
||||
status != NS_ERROR_DEFINITIVE_UNKNOWN_HOST) {
|
||||
// the errors are not failed resolves, that means
|
||||
// something else failed, consider this as *TRR not used*
|
||||
// for actually trying to resolve the host
|
||||
addrRec->mTRRUsed = false;
|
||||
} else {
|
||||
MOZ_ASSERT(0);
|
||||
addrRec->mTRRUsed = true;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(status)) {
|
||||
addrRec->mTRRSuccess++;
|
||||
if (addrRec->mTRRSuccess == 1) {
|
||||
// Store the duration on first succesful TRR response. We
|
||||
// don't know that there will be a second response nor can we
|
||||
// tell which of two has useful data.
|
||||
addrRec->mTrrDuration = TimeStamp::Now() - addrRec->mTrrStart;
|
||||
}
|
||||
}
|
||||
if (TRROutstanding()) {
|
||||
addrRec->mFirstTRRresult = status;
|
||||
if (NS_FAILED(status)) {
|
||||
return LOOKUP_OK; // wait for outstanding
|
||||
}
|
||||
|
||||
// There's another TRR complete pending. Wait for it and keep
|
||||
// this RRset around until then.
|
||||
MOZ_ASSERT(!addrRec->mFirstTRR && newRRSet);
|
||||
addrRec->mFirstTRR.swap(newRRSet); // autoPtr.swap()
|
||||
MOZ_ASSERT(addrRec->mFirstTRR && !newRRSet);
|
||||
|
||||
if (addrRec->mDidCallbacks) {
|
||||
return LOOKUP_OK;
|
||||
}
|
||||
|
||||
if (gTRRService && StaticPrefs::network_trr_wait_for_A_and_AAAA()) {
|
||||
LOG(("CompleteLookup: waiting for all responses!\n"));
|
||||
return LOOKUP_OK;
|
||||
}
|
||||
|
||||
if (addrRec->mTrrA && !StaticPrefs::network_trr_early_AAAA()) {
|
||||
// This is an early AAAA with a pending A response. Allowed
|
||||
// only by pref.
|
||||
LOG(("CompleteLookup: avoiding early use of TRR AAAA!\n"));
|
||||
return LOOKUP_OK;
|
||||
}
|
||||
|
||||
// we can do some callbacks with this partial result which requires
|
||||
// a deep copy
|
||||
newRRSet = new AddrInfo(addrRec->mFirstTRR);
|
||||
MOZ_ASSERT(addrRec->mFirstTRR && newRRSet);
|
||||
|
||||
} else {
|
||||
// no more outstanding TRRs
|
||||
// If mFirstTRR is set, merge those addresses into current set!
|
||||
if (addrRec->mFirstTRR) {
|
||||
if (NS_SUCCEEDED(status)) {
|
||||
LOG(("Merging responses"));
|
||||
newRRSet = merge_rrset(newRRSet, addrRec->mFirstTRR);
|
||||
} else {
|
||||
LOG(("Will use previous response"));
|
||||
newRRSet.swap(addrRec->mFirstTRR); // transfers
|
||||
// We must use the status of the first response, otherwise we'll
|
||||
// pass an error result to the consumers.
|
||||
status = addrRec->mFirstTRRresult;
|
||||
}
|
||||
addrRec->mFirstTRR = nullptr;
|
||||
}
|
||||
|
||||
if (NS_FAILED(addrRec->mFirstTRRresult) && NS_FAILED(status) &&
|
||||
(addrRec->mFirstTRRresult != NS_ERROR_UNKNOWN_HOST) &&
|
||||
(status != NS_ERROR_UNKNOWN_HOST) &&
|
||||
(addrRec->mFirstTRRresult != NS_ERROR_DEFINITIVE_UNKNOWN_HOST) &&
|
||||
(status != NS_ERROR_DEFINITIVE_UNKNOWN_HOST)) {
|
||||
// the errors are not failed resolves, that means
|
||||
// something else failed, consider this as *TRR not used*
|
||||
// for actually trying to resolve the host
|
||||
addrRec->mTRRUsed = false;
|
||||
}
|
||||
|
||||
if (!addrRec->mTRRSuccess) {
|
||||
// no TRR success
|
||||
newRRSet = nullptr;
|
||||
|
||||
// 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);
|
||||
}
|
||||
if (NS_FAILED(status)) {
|
||||
if (aReason != nsHostRecord::TRR_UNSET) {
|
||||
addrRec->RecordReason(aReason);
|
||||
} else {
|
||||
// At least one TRR request succeeded. We mark the response OK.
|
||||
addrRec->RecordReason(nsHostRecord::TRR_OK);
|
||||
// Unknown failed reason.
|
||||
addrRec->RecordReason(nsHostRecord::TRR_FAILED);
|
||||
}
|
||||
|
||||
if (!addrRec->mTRRSuccess &&
|
||||
addrRec->mEffectiveTRRMode == nsIRequest::TRR_FIRST_MODE &&
|
||||
addrRec->mFirstTRRresult != NS_ERROR_DEFINITIVE_UNKNOWN_HOST &&
|
||||
status != NS_ERROR_DEFINITIVE_UNKNOWN_HOST) {
|
||||
MOZ_ASSERT(!addrRec->mResolving);
|
||||
NativeLookup(addrRec);
|
||||
MOZ_ASSERT(addrRec->mResolving);
|
||||
return LOOKUP_OK;
|
||||
}
|
||||
|
||||
if (addrRec->mTRRSuccess && mNCS &&
|
||||
(mNCS->GetNAT64() == nsINetworkConnectivityService::OK) && newRRSet) {
|
||||
newRRSet = mNCS->MapNAT64IPs(newRRSet);
|
||||
}
|
||||
|
||||
if (NS_FAILED(status)) {
|
||||
// This is the error that consumers expect.
|
||||
status = NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
// continue
|
||||
} else {
|
||||
addrRec->mTRRSuccess++;
|
||||
addrRec->RecordReason(nsHostRecord::TRR_OK);
|
||||
}
|
||||
|
||||
if (NS_FAILED(status) &&
|
||||
addrRec->mEffectiveTRRMode == nsIRequest::TRR_FIRST_MODE &&
|
||||
status != NS_ERROR_DEFINITIVE_UNKNOWN_HOST) {
|
||||
MOZ_ASSERT(!addrRec->mResolving);
|
||||
NativeLookup(addrRec);
|
||||
MOZ_ASSERT(addrRec->mResolving);
|
||||
return LOOKUP_OK;
|
||||
}
|
||||
|
||||
if (!addrRec->mTRRSuccess) {
|
||||
// no TRR success
|
||||
newRRSet = nullptr;
|
||||
}
|
||||
|
||||
if (NS_FAILED(status)) {
|
||||
// This is the error that consumers expect.
|
||||
status = NS_ERROR_UNKNOWN_HOST;
|
||||
}
|
||||
} else { // native resolve completed
|
||||
if (addrRec->usingAnyThread) {
|
||||
mActiveAnyThreadCount--;
|
||||
@ -2171,15 +1940,6 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
|
||||
PrepareRecordExpirationAddrRecord(addrRec);
|
||||
}
|
||||
|
||||
bool doCallbacks = true;
|
||||
|
||||
if (trrResult && addrRec->mDidCallbacks) {
|
||||
// already callback'ed on the first TRR response
|
||||
LOG(("nsHostResolver Suppressing callback for second TRR response for %s\n",
|
||||
addrRec->host.get()));
|
||||
doCallbacks = false;
|
||||
}
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
MutexAutoLock lock(addrRec->addr_info_lock);
|
||||
if (addrRec->addr_info) {
|
||||
@ -2193,22 +1953,27 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
|
||||
}
|
||||
}
|
||||
|
||||
if (doCallbacks) {
|
||||
// get the list of pending callbacks for this lookup, and notify
|
||||
// them that the lookup is complete.
|
||||
mozilla::LinkedList<RefPtr<nsResolveHostCallback>> cbs =
|
||||
std::move(rec->mCallbacks);
|
||||
// get the list of pending callbacks for this lookup, and notify
|
||||
// them that the lookup is complete.
|
||||
mozilla::LinkedList<RefPtr<nsResolveHostCallback>> cbs =
|
||||
std::move(rec->mCallbacks);
|
||||
|
||||
LOG(("nsHostResolver record %p calling back dns users\n", addrRec.get()));
|
||||
LOG(("nsHostResolver record %p calling back dns users status:%X\n",
|
||||
addrRec.get(), int(status)));
|
||||
|
||||
for (nsResolveHostCallback* c = cbs.getFirst(); c;
|
||||
c = c->removeAndGetNext()) {
|
||||
c->OnResolveHostComplete(this, rec, status);
|
||||
}
|
||||
addrRec->mDidCallbacks = true;
|
||||
for (nsResolveHostCallback* c = cbs.getFirst(); c;
|
||||
c = c->removeAndGetNext()) {
|
||||
c->OnResolveHostComplete(this, rec, status);
|
||||
}
|
||||
|
||||
if (!addrRec->mResolving && !mShutdown) {
|
||||
{
|
||||
auto trrQuery = addrRec->mTRRQuery.Lock();
|
||||
if (trrQuery.ref()) {
|
||||
addrRec->mTrrDuration = trrQuery.ref()->Duration();
|
||||
}
|
||||
trrQuery.ref() = nullptr;
|
||||
}
|
||||
addrRec->ResolveComplete();
|
||||
|
||||
AddToEvictionQ(rec);
|
||||
@ -2250,8 +2015,10 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookupByType(
|
||||
MOZ_ASSERT(typeRec->mResolving);
|
||||
typeRec->mResolving--;
|
||||
|
||||
MutexAutoLock trrlock(typeRec->mTrrLock);
|
||||
typeRec->mTrr = nullptr;
|
||||
{
|
||||
auto lock = rec->mTRRQuery.Lock();
|
||||
lock.ref() = nullptr;
|
||||
}
|
||||
|
||||
uint32_t duration = static_cast<uint32_t>(
|
||||
(TimeStamp::Now() - typeRec->mStart).ToMilliseconds());
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "prnetdb.h"
|
||||
#include "PLDHashTable.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsIDNSListener.h"
|
||||
@ -34,6 +35,7 @@ class nsResolveHostCallback;
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
class TRR;
|
||||
class TRRQuery;
|
||||
enum ResolverMode {
|
||||
MODE_NATIVEONLY, // 0 - TRR OFF (by default)
|
||||
MODE_RESERVED1, // 1 - Reserved value. Used to be parallel resolve.
|
||||
@ -133,6 +135,7 @@ class nsHostRecord : public mozilla::LinkedListElement<RefPtr<nsHostRecord>>,
|
||||
protected:
|
||||
friend class nsHostResolver;
|
||||
friend class mozilla::net::TRR;
|
||||
friend class mozilla::net::TRRQuery;
|
||||
|
||||
explicit nsHostRecord(const nsHostKey& key);
|
||||
virtual ~nsHostRecord() = default;
|
||||
@ -165,8 +168,7 @@ class nsHostRecord : public mozilla::LinkedListElement<RefPtr<nsHostRecord>>,
|
||||
};
|
||||
static DnsPriority GetPriority(uint16_t aFlags);
|
||||
|
||||
virtual void Cancel() {}
|
||||
|
||||
virtual void Cancel();
|
||||
virtual bool HasUsableResultInternal() const { return false; }
|
||||
|
||||
mozilla::LinkedList<RefPtr<nsResolveHostCallback>> mCallbacks;
|
||||
@ -197,7 +199,10 @@ class nsHostRecord : public mozilla::LinkedListElement<RefPtr<nsHostRecord>>,
|
||||
TRRSkippedReason mTRRAFailReason = TRR_UNSET;
|
||||
TRRSkippedReason mTRRAAAAFailReason = TRR_UNSET;
|
||||
|
||||
uint16_t mResolving; // counter of outstanding resolving calls
|
||||
mozilla::DataMutex<RefPtr<mozilla::net::TRRQuery>> mTRRQuery;
|
||||
|
||||
mozilla::Atomic<int32_t>
|
||||
mResolving; // counter of outstanding resolving calls
|
||||
|
||||
uint8_t negative : 1; /* True if this record is a cache of a failed
|
||||
lookup. Negative cache entries are valid just
|
||||
@ -254,6 +259,7 @@ class AddrHostRecord final : public nsHostRecord {
|
||||
private:
|
||||
friend class nsHostResolver;
|
||||
friend class mozilla::net::TRR;
|
||||
friend class mozilla::net::TRRQuery;
|
||||
|
||||
explicit AddrHostRecord(const nsHostKey& key);
|
||||
~AddrHostRecord();
|
||||
@ -261,8 +267,6 @@ class AddrHostRecord final : public nsHostRecord {
|
||||
// Checks if the record is usable (not expired and has a value)
|
||||
bool HasUsableResultInternal() const override;
|
||||
|
||||
void Cancel() override;
|
||||
|
||||
bool RemoveOrRefresh(bool aTrrToo); // Mark records currently being resolved
|
||||
// as needed to resolve again.
|
||||
|
||||
@ -281,9 +285,6 @@ class AddrHostRecord final : public nsHostRecord {
|
||||
mozilla::TimeDuration mTrrDuration;
|
||||
mozilla::TimeDuration mNativeDuration;
|
||||
|
||||
RefPtr<mozilla::net::AddrInfo> mFirstTRR; // partial TRR storage
|
||||
nsresult mFirstTRRresult;
|
||||
|
||||
mozilla::Atomic<bool> mTRRUsed; // TRR was used on this record
|
||||
uint8_t mTRRSuccess; // number of successful TRR responses
|
||||
uint8_t mNativeSuccess; // number of native lookup responses
|
||||
@ -296,19 +297,12 @@ class AddrHostRecord final : public nsHostRecord {
|
||||
// given to getaddrinfo())
|
||||
uint16_t usingAnyThread : 1; // true if off queue and contributing to
|
||||
// mActiveAnyThreadCount
|
||||
uint16_t mDidCallbacks : 1;
|
||||
uint16_t mGetTtl : 1;
|
||||
|
||||
// when the results from this resolve is returned, it is not to be
|
||||
// trusted, but instead a new resolve must be made!
|
||||
uint16_t mResolveAgain : 1;
|
||||
|
||||
enum { INIT, STARTED, OK, FAILED } mTrrAUsed, mTrrAAAAUsed;
|
||||
|
||||
Mutex mTrrLock; // lock when accessing the mTrrA[AAA] pointers
|
||||
RefPtr<mozilla::net::TRR> mTrrA;
|
||||
RefPtr<mozilla::net::TRR> mTrrAAAA;
|
||||
|
||||
// The number of times ReportUnusable() has been called in the record's
|
||||
// lifetime.
|
||||
uint32_t mUnusableCount = 0;
|
||||
@ -345,6 +339,7 @@ class TypeHostRecord final : public nsHostRecord,
|
||||
|
||||
private:
|
||||
friend class nsHostResolver;
|
||||
friend class mozilla::net::TRRQuery;
|
||||
|
||||
explicit TypeHostRecord(const nsHostKey& key);
|
||||
~TypeHostRecord();
|
||||
@ -352,13 +347,8 @@ class TypeHostRecord final : public nsHostRecord,
|
||||
// Checks if the record is usable (not expired and has a value)
|
||||
bool HasUsableResultInternal() const override;
|
||||
|
||||
void Cancel() override;
|
||||
|
||||
bool HasUsableResult();
|
||||
|
||||
mozilla::Mutex mTrrLock; // lock when accessing the mTrr pointer
|
||||
RefPtr<mozilla::net::TRR> mTrr;
|
||||
|
||||
mozilla::net::TypeRecordResultType mResults = AsVariant(mozilla::Nothing());
|
||||
mozilla::Mutex mResultsLock;
|
||||
|
||||
@ -495,6 +485,7 @@ class nsHostResolver : public nsISupports, public AHostResolver {
|
||||
nsResolveHostCallback* callback);
|
||||
|
||||
nsHostRecord* InitRecord(const nsHostKey& key);
|
||||
mozilla::net::NetworkConnectivityService* GetNCS() { return mNCS; }
|
||||
|
||||
/**
|
||||
* return a resolved hard coded loopback dns record for the specified key
|
||||
|
Loading…
Reference in New Issue
Block a user