tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 7496c8515212669451d7e775a00c2be07da38ca5
parent a2586e4723b725d111ec72b3f090d1ecd62a04c7
Author: Cosmin Sabou <csabou@mozilla.com>
Date:   Tue,  9 Dec 2025 16:28:55 +0200

Revert "Bug 1999691 - When a DNS cache entry is used, take it out and readd it to the eviction queue, r=necko-reviewers,valentin" for causing a top crash tracked under Bug 2004939.

This reverts commit ffb7bd5a17789fa1b0961865b6e9b945f8babde2.

Diffstat:
Mmodules/libpref/init/StaticPrefList.yaml | 7-------
Mnetwerk/dns/HostRecordQueue.cpp | 15---------------
Mnetwerk/dns/HostRecordQueue.h | 5-----
Mnetwerk/dns/nsHostResolver.cpp | 25++++++++-----------------
Mnetwerk/dns/nsHostResolver.h | 11+++++------
Dnetwerk/test/gtest/TestHostRecordQueue.cpp | 120-------------------------------------------------------------------------------
Mnetwerk/test/gtest/moz.build | 2--
7 files changed, 13 insertions(+), 172 deletions(-)

diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml @@ -15666,13 +15666,6 @@ value: "" mirror: never -# When true, placing the most recent used cache entry -# to the tail of the EvictionQ. -- name: network.dns.mru_to_tail - type: RelaxedAtomicBool - value: @IS_NIGHTLY_BUILD@ - mirror: always - # Whether to add additional record IPs to the cache - name: network.trr.add_additional_records type: RelaxedAtomicBool diff --git a/netwerk/dns/HostRecordQueue.cpp b/netwerk/dns/HostRecordQueue.cpp @@ -92,21 +92,6 @@ void HostRecordQueue::AddToEvictionQ( } } -void HostRecordQueue::MoveToEvictionQueueTail( - nsHostRecord* aRec, const MutexAutoLock& aProofOfLock) { - bool inEvictionQ = mEvictionQ.contains(aRec); - if (!inEvictionQ) { - // Note: this function can be called when the record isn’t in the - // mEvictionQ. For example, if we immediately start a TTL lookup (see - // nsHostResolver::CompleteLookupLocked), the record may not be in - // mEvictionQ. - return; - } - - aRec->remove(); - mEvictionQ.insertBack(aRec); -} - void HostRecordQueue::MaybeRenewHostRecord(nsHostRecord* aRec, const MutexAutoLock& aProofOfLock) { if (!aRec->isInList()) { diff --git a/netwerk/dns/HostRecordQueue.h b/netwerk/dns/HostRecordQueue.h @@ -34,11 +34,6 @@ class HostRecordQueue final { nsHostRecord* aRec, uint32_t aMaxCacheEntries, nsRefPtrHashtable<nsGenericHashKey<nsHostKey>, nsHostRecord>& aDB, const MutexAutoLock& aProofOfLock); - - // Move aRec to the tail of mEvictionQ (the most-recently-used end). - void MoveToEvictionQueueTail(nsHostRecord* aRec, - const MutexAutoLock& aProofOfLock); - // Called for removing the record from mEvictionQ. When this function is // called, the record should be either in mEvictionQ or not in any queue. void MaybeRenewHostRecord(nsHostRecord* aRec, diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp @@ -591,7 +591,7 @@ nsresult nsHostResolver::ResolveHost(const nsACString& aHost, } else if (!rec->mResolving) { result = FromUnspecEntry(rec, host, aTrrServer, originSuffix, type, flags, af, - aOriginAttributes.IsPrivateBrowsing(), status, lock); + aOriginAttributes.IsPrivateBrowsing(), status); // If this is a by-type request or if no valid record was found // in the cache or this is an AF_UNSPEC request, then start a // new lookup. @@ -675,14 +675,12 @@ already_AddRefed<nsHostRecord> nsHostResolver::FromCache( // but start a new lookup in the background. // // Also records telemetry for type of cache hit (HIT/NEGATIVE_HIT/RENEWAL). - bool refresh = ConditionallyRefreshRecord(aRec, aHost, aLock); + ConditionallyRefreshRecord(aRec, aHost, aLock); if (aRec->negative) { LOG((" Negative cache entry for host [%s].\n", nsPromiseFlatCString(aHost).get())); aStatus = NS_ERROR_UNKNOWN_HOST; - } else if (StaticPrefs::network_dns_mru_to_tail() && !refresh) { - mQueue.MoveToEvictionQueueTail(aRec, aLock); } return result.forget(); @@ -709,8 +707,7 @@ already_AddRefed<nsHostRecord> nsHostResolver::FromIPLiteral( already_AddRefed<nsHostRecord> nsHostResolver::FromUnspecEntry( nsHostRecord* aRec, const nsACString& aHost, const nsACString& aTrrServer, const nsACString& aOriginSuffix, uint16_t aType, - nsIDNSService::DNSFlags aFlags, uint16_t af, bool aPb, nsresult& aStatus, - const MutexAutoLock& aLock) { + nsIDNSService::DNSFlags aFlags, uint16_t af, bool aPb, nsresult& aStatus) { RefPtr<nsHostRecord> result = nullptr; // If this is an IPV4 or IPV6 specific request, check if there is // an AF_UNSPEC entry we can use. Otherwise, hit the resolver... @@ -776,10 +773,7 @@ already_AddRefed<nsHostRecord> nsHostResolver::FromUnspecEntry( if (aRec->negative) { aStatus = NS_ERROR_UNKNOWN_HOST; } - bool refresh = ConditionallyRefreshRecord(aRec, aHost, lock); - if (!refresh) { - AddToEvictionQ(result, aLock); - } + ConditionallyRefreshRecord(aRec, aHost, lock); } else if (af == PR_AF_INET6) { // For AF_INET6, a new lookup means another AF_UNSPEC // lookup. We have already iterated through the @@ -1189,15 +1183,14 @@ nsresult nsHostResolver::NameLookup(nsHostRecord* rec, return rv; } -bool nsHostResolver::ConditionallyRefreshRecord(nsHostRecord* rec, - const nsACString& host, - const MutexAutoLock& aLock) { +nsresult nsHostResolver::ConditionallyRefreshRecord( + nsHostRecord* rec, const nsACString& host, const MutexAutoLock& aLock) { if ((rec->CheckExpiration(TimeStamp::NowLoRes()) == nsHostRecord::EXP_GRACE || rec->negative) && !rec->mResolving && rec->RefreshForNegativeResponse()) { LOG((" Using %s cache entry for host [%s] but starting async renewal.", rec->negative ? "negative" : "positive", host.BeginReading())); - nsresult rv = NameLookup(rec, aLock); + NameLookup(rec, aLock); if (rec->IsAddrRecord()) { if (!rec->negative) { @@ -1206,8 +1199,6 @@ bool nsHostResolver::ConditionallyRefreshRecord(nsHostRecord* rec, glean::dns::lookup_method.AccumulateSingleSample(METHOD_NEGATIVE_HIT); } } - - return NS_SUCCEEDED(rv); } else if (rec->IsAddrRecord()) { // it could be that the record is negative, but we haven't entered the above // if condition due to the second expression being false. In that case we @@ -1219,7 +1210,7 @@ bool nsHostResolver::ConditionallyRefreshRecord(nsHostRecord* rec, } } - return false; + return NS_OK; } bool nsHostResolver::GetHostToLookup(nsHostRecord** result) { diff --git a/netwerk/dns/nsHostResolver.h b/netwerk/dns/nsHostResolver.h @@ -234,13 +234,12 @@ class nsHostResolver : public nsISupports, public AHostResolver { /** * Starts a new lookup in the background for cached entries that are in the - * grace period or that are are negative. Return true when the new lookup - * starts. + * grace period or that are are negative. * * Also records telemetry for type of cache hit (HIT/NEGATIVE_HIT/RENEWAL). */ - bool ConditionallyRefreshRecord(nsHostRecord* rec, const nsACString& host, - const mozilla::MutexAutoLock& aLock) + nsresult ConditionallyRefreshRecord(nsHostRecord* rec, const nsACString& host, + const mozilla::MutexAutoLock& aLock) MOZ_REQUIRES(mLock); void OnResolveComplete(nsHostRecord* aRec, @@ -267,8 +266,8 @@ class nsHostResolver : public nsISupports, public AHostResolver { already_AddRefed<nsHostRecord> FromUnspecEntry( nsHostRecord* aRec, const nsACString& aHost, const nsACString& aTrrServer, const nsACString& aOriginSuffix, uint16_t aType, - nsIDNSService::DNSFlags aFlags, uint16_t af, bool aPb, nsresult& aStatus, - const mozilla::MutexAutoLock& aLock) MOZ_REQUIRES(mLock); + nsIDNSService::DNSFlags aFlags, uint16_t af, bool aPb, nsresult& aStatus) + MOZ_REQUIRES(mLock); enum { METHOD_HIT = 1, diff --git a/netwerk/test/gtest/TestHostRecordQueue.cpp b/netwerk/test/gtest/TestHostRecordQueue.cpp @@ -1,120 +0,0 @@ -#include "gtest/gtest.h" - -#include "HostRecordQueue.h" -#include "TRRQuery.h" -#include "TRR.h" - -using namespace mozilla; -using namespace mozilla::net; - -class MockHostRecord : public nsHostRecord { - public: - NS_DECL_ISUPPORTS_INHERITED - explicit MockHostRecord(const nsHostKey& aKey) : nsHostRecord(aKey) { - negative = true; - } - - void ResolveComplete() override {} - - bool HasUsableResultInternal( - const mozilla::TimeStamp& now, - nsIDNSService::DNSFlags queryFlags) const override { - return true; - } - - private: - ~MockHostRecord() = default; -}; - -NS_IMPL_ISUPPORTS_INHERITED(MockHostRecord, nsHostRecord, MockHostRecord) - -class HostRecordQueueTest : public ::testing::Test { - protected: - void SetUp() override {} - - HostRecordQueue queue; - Mutex mMutex{"HostRecordQueueTest"}; - nsRefPtrHashtable<nsGenericHashKey<nsHostKey>, nsHostRecord> mDB; -}; - -static RefPtr<nsHostRecord> CreateAndInsertMockRecord( - nsRefPtrHashtable<nsGenericHashKey<nsHostKey>, nsHostRecord>& aDB, - const char* hostName) { - nsHostKey key(nsCString(hostName), ""_ns, 0, - nsIDNSService::RESOLVE_DEFAULT_FLAGS, 0, false, ""_ns); - return aDB.LookupOrInsertWith(key, [&] { return new MockHostRecord(key); }); -} - -TEST_F(HostRecordQueueTest, AddToEvictionQ_BelowMax) { - RefPtr<nsHostRecord> rec = CreateAndInsertMockRecord(mDB, "A.com"); - - MutexAutoLock lock(mMutex); - - queue.AddToEvictionQ(rec.get(), 100, mDB, lock); - - ASSERT_EQ(1u, queue.EvictionQSize()); - ASSERT_TRUE(rec->isInList()); - - // Cleanup - rec->remove(); -} - -// When the eviction queue is at capacity, adding a new entry evicts the -// oldest (head) entry. -TEST_F(HostRecordQueueTest, AddToEvictionQ_AtMax_EvictsOldest) { - const uint32_t MAX_ENTRIES = 3; - - RefPtr<nsHostRecord> rec1 = CreateAndInsertMockRecord(mDB, "A.com"); - RefPtr<nsHostRecord> rec2 = CreateAndInsertMockRecord(mDB, "B.com"); - RefPtr<nsHostRecord> rec3 = CreateAndInsertMockRecord(mDB, "C.com"); - - MutexAutoLock lock(mMutex); - queue.AddToEvictionQ(rec1, MAX_ENTRIES, mDB, lock); - queue.AddToEvictionQ(rec2, MAX_ENTRIES, mDB, lock); - queue.AddToEvictionQ(rec3, MAX_ENTRIES, mDB, lock); - - ASSERT_EQ(MAX_ENTRIES, queue.EvictionQSize()); - - RefPtr<nsHostRecord> rec4 = CreateAndInsertMockRecord(mDB, "New.com"); - queue.AddToEvictionQ(rec4, MAX_ENTRIES, mDB, lock); - - ASSERT_TRUE(rec2->isInList()); - ASSERT_TRUE(rec3->isInList()); - ASSERT_TRUE(rec4->isInList()); - ASSERT_FALSE(rec1->isInList()); - - rec2->remove(); - rec3->remove(); - rec4->remove(); -} - -// After adding a new record, the touched entry -// remains, and the oldest untouched entry is evicted. -TEST_F(HostRecordQueueTest, MoveToEvictionQueueTail) { - const uint32_t MAX_ENTRIES = 3; - - RefPtr<nsHostRecord> rec1 = CreateAndInsertMockRecord(mDB, "A.com"); - RefPtr<nsHostRecord> rec2 = CreateAndInsertMockRecord(mDB, "B.com"); - RefPtr<nsHostRecord> rec3 = CreateAndInsertMockRecord(mDB, "C.com"); - - MutexAutoLock lock(mMutex); - queue.AddToEvictionQ(rec1, MAX_ENTRIES, mDB, lock); - queue.AddToEvictionQ(rec2, MAX_ENTRIES, mDB, lock); - queue.AddToEvictionQ(rec3, MAX_ENTRIES, mDB, lock); - - ASSERT_EQ(MAX_ENTRIES, queue.EvictionQSize()); - - queue.MoveToEvictionQueueTail(rec1, lock); - - RefPtr<nsHostRecord> rec4 = CreateAndInsertMockRecord(mDB, "New.com"); - queue.AddToEvictionQ(rec4, MAX_ENTRIES, mDB, lock); - - ASSERT_TRUE(rec1->isInList()); - ASSERT_TRUE(rec3->isInList()); - ASSERT_TRUE(rec4->isInList()); - ASSERT_FALSE(rec2->isInList()); - - rec1->remove(); - rec3->remove(); - rec4->remove(); -} diff --git a/netwerk/test/gtest/moz.build b/netwerk/test/gtest/moz.build @@ -16,7 +16,6 @@ UNIFIED_SOURCES += [ "TestDNSPacket.cpp", "TestEtcHostsParsing.cpp", "TestHeaders.cpp", - "TestHostRecordQueue.cpp", "TestHttp2WebTransport.cpp", "TestHttp3ConnectUDPStream.cpp", "TestHttpAtom.cpp", @@ -70,7 +69,6 @@ LOCAL_INCLUDES += [ "/netwerk/base", "/netwerk/cache2", "/netwerk/cookie", - "/netwerk/dns", "/netwerk/protocol/http", "/toolkit/components/jsoncpp/include", "/xpcom/tests/gtest",