diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 261b6262119d..06909bf196dc 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -698,6 +698,16 @@ OnloadBlocker::GetLoadFlags(nsLoadFlags* aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +OnloadBlocker::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +OnloadBlocker::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP OnloadBlocker::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp index 9bab2286edf3..b0c592ad519d 100644 --- a/dom/ipc/BrowserParent.cpp +++ b/dom/ipc/BrowserParent.cpp @@ -3630,6 +3630,8 @@ class FakeChannel final : public nsIChannel, NS_IMETHOD SetLoadGroup(nsILoadGroup*) NO_IMPL; NS_IMETHOD SetLoadFlags(nsLoadFlags) NO_IMPL; NS_IMETHOD GetLoadFlags(nsLoadFlags*) NO_IMPL; + NS_IMETHOD GetTRRMode(nsIRequest::TRRMode* aTRRMode) NO_IMPL; + NS_IMETHOD SetTRRMode(nsIRequest::TRRMode aMode) NO_IMPL; NS_IMETHOD GetIsDocument(bool*) NO_IMPL; NS_IMETHOD GetOriginalURI(nsIURI**) NO_IMPL; NS_IMETHOD SetOriginalURI(nsIURI*) NO_IMPL; diff --git a/dom/ipc/RemoteWebProgressRequest.cpp b/dom/ipc/RemoteWebProgressRequest.cpp index 6d0373243a6b..1fdbda2116c2 100644 --- a/dom/ipc/RemoteWebProgressRequest.cpp +++ b/dom/ipc/RemoteWebProgressRequest.cpp @@ -227,6 +227,16 @@ NS_IMETHODIMP RemoteWebProgressRequest::GetLoadFlags(nsLoadFlags* aLoadFlags) { return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP RemoteWebProgressRequest::GetTRRMode( + nsIRequest::TRRMode* aTRRMode) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP RemoteWebProgressRequest::SetTRRMode( + nsIRequest::TRRMode aTRRMode) { + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP RemoteWebProgressRequest::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp index 88d69fad5719..37f126c7236e 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -836,6 +836,16 @@ nsJSChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { return mStreamChannel->SetLoadFlags(aLoadFlags); } +NS_IMETHODIMP +nsJSChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsJSChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsJSChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) { return mStreamChannel->GetLoadGroup(aLoadGroup); diff --git a/dom/presentation/PresentationConnection.cpp b/dom/presentation/PresentationConnection.cpp index 18e6f9676d5e..0aa60a2ecf1c 100644 --- a/dom/presentation/PresentationConnection.cpp +++ b/dom/presentation/PresentationConnection.cpp @@ -676,6 +676,16 @@ PresentationConnection::GetLoadFlags(nsLoadFlags* aLoadFlags) { NS_IMETHODIMP PresentationConnection::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +PresentationConnection::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +PresentationConnection::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + nsresult PresentationConnection::AddIntoLoadGroup() { // Avoid adding to loadgroup multiple times if (mWeakLoadGroup) { diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp index 5edc956b7630..7afc3203b7d5 100644 --- a/dom/serviceworkers/ServiceWorkerManager.cpp +++ b/dom/serviceworkers/ServiceWorkerManager.cpp @@ -1509,11 +1509,10 @@ void ServiceWorkerManager::LoadRegistration( registration->SetLastUpdateTime(aRegistration.lastUpdateTime()); nsLoadFlags importsLoadFlags = nsIChannel::LOAD_BYPASS_SERVICE_WORKER; - importsLoadFlags |= - aRegistration.updateViaCache() == - static_cast(ServiceWorkerUpdateViaCache::None) - ? nsIRequest::LOAD_NORMAL - : nsIRequest::VALIDATE_ALWAYS; + if (aRegistration.updateViaCache() != + static_cast(ServiceWorkerUpdateViaCache::None)) { + importsLoadFlags |= nsIRequest::VALIDATE_ALWAYS; + } const nsCString& currentWorkerURL = aRegistration.currentWorkerURL(); if (!currentWorkerURL.IsEmpty()) { diff --git a/dom/websocket/WebSocket.cpp b/dom/websocket/WebSocket.cpp index 23101f5f84cb..170bcc594849 100644 --- a/dom/websocket/WebSocket.cpp +++ b/dom/websocket/WebSocket.cpp @@ -2545,6 +2545,16 @@ WebSocketImpl::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +WebSocketImpl::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +WebSocketImpl::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + namespace { class WorkerRunnableDispatcher final : public WorkerRunnable { diff --git a/image/decoders/icon/mac/nsIconChannelCocoa.mm b/image/decoders/icon/mac/nsIconChannelCocoa.mm index 999f6e39e822..f43848804e51 100644 --- a/image/decoders/icon/mac/nsIconChannelCocoa.mm +++ b/image/decoders/icon/mac/nsIconChannelCocoa.mm @@ -353,6 +353,12 @@ nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes) { return mPump->SetLoadFlags(aLoadAttributes); } +NS_IMETHODIMP +nsIconChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { return GetTRRModeImpl(aTRRMode); } + +NS_IMETHODIMP +nsIconChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { return SetTRRModeImpl(aTRRMode); } + NS_IMETHODIMP nsIconChannel::GetIsDocument(bool* aIsDocument) { return NS_GetIsDocumentChannel(this, aIsDocument); diff --git a/image/decoders/icon/win/nsIconChannel.cpp b/image/decoders/icon/win/nsIconChannel.cpp index 20a5c82352a4..56437ccb0104 100644 --- a/image/decoders/icon/win/nsIconChannel.cpp +++ b/image/decoders/icon/win/nsIconChannel.cpp @@ -239,6 +239,16 @@ nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes) { return mPump->SetLoadFlags(aLoadAttributes); } +NS_IMETHODIMP +nsIconChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsIconChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsIconChannel::GetIsDocument(bool* aIsDocument) { return NS_GetIsDocumentChannel(this, aIsDocument); diff --git a/image/imgRequestProxy.cpp b/image/imgRequestProxy.cpp index 3492d600521a..e0b60822cfe2 100644 --- a/image/imgRequestProxy.cpp +++ b/image/imgRequestProxy.cpp @@ -249,9 +249,7 @@ void imgRequestProxy::ClearValidating() { } } -bool imgRequestProxy::IsOnEventTarget() const { - return true; -} +bool imgRequestProxy::IsOnEventTarget() const { return true; } already_AddRefed imgRequestProxy::GetEventTarget() const { nsCOMPtr target(mEventTarget); @@ -644,6 +642,16 @@ imgRequestProxy::SetLoadFlags(nsLoadFlags flags) { return NS_OK; } +NS_IMETHODIMP +imgRequestProxy::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +imgRequestProxy::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + /** imgIRequest methods **/ NS_IMETHODIMP diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp index d8d8060795e0..f64d360087e7 100644 --- a/modules/libjar/nsJARChannel.cpp +++ b/modules/libjar/nsJARChannel.cpp @@ -617,6 +617,16 @@ nsJARChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +nsJARChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsJARChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsJARChannel::GetIsDocument(bool* aIsDocument) { return NS_GetIsDocumentChannel(this, aIsDocument); diff --git a/netwerk/base/NetworkConnectivityService.cpp b/netwerk/base/NetworkConnectivityService.cpp index 86239a059f92..1780597d9f5b 100644 --- a/netwerk/base/NetworkConnectivityService.cpp +++ b/netwerk/base/NetworkConnectivityService.cpp @@ -200,10 +200,11 @@ static inline already_AddRefed SetupIPCheckChannel(bool ipv4) { nullptr, // aPerformanceStorage nullptr, // aLoadGroup nullptr, - nsIRequest::LOAD_BYPASS_CACHE | // don't read from the cache - nsIRequest::INHIBIT_CACHING | // don't write the response to cache - nsIRequest::LOAD_DISABLE_TRR | // check network capabilities not TRR - nsIRequest::LOAD_ANONYMOUS); // prevent privacy leaks + nsIRequest::LOAD_BYPASS_CACHE | // don't read from the cache + nsIRequest::INHIBIT_CACHING | // don't write the response to cache + nsIRequest::LOAD_ANONYMOUS); // prevent privacy leaks + + channel->SetTRRMode(nsIRequest::TRR_DISABLED_MODE); NS_ENSURE_SUCCESS(rv, nullptr); diff --git a/netwerk/base/nsAsyncStreamCopier.cpp b/netwerk/base/nsAsyncStreamCopier.cpp index faa4c5f09a99..eeb2666c14a3 100644 --- a/netwerk/base/nsAsyncStreamCopier.cpp +++ b/netwerk/base/nsAsyncStreamCopier.cpp @@ -202,6 +202,16 @@ nsAsyncStreamCopier::GetLoadFlags(nsLoadFlags* aLoadFlags) { NS_IMETHODIMP nsAsyncStreamCopier::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +nsAsyncStreamCopier::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return nsIAsyncStreamCopier::GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsAsyncStreamCopier::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return nsIAsyncStreamCopier::SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsAsyncStreamCopier::GetLoadGroup(nsILoadGroup** aLoadGroup) { *aLoadGroup = nullptr; diff --git a/netwerk/base/nsBaseChannel.cpp b/netwerk/base/nsBaseChannel.cpp index 3bc99a48b55a..d6ae12f568a2 100644 --- a/netwerk/base/nsBaseChannel.cpp +++ b/netwerk/base/nsBaseChannel.cpp @@ -432,6 +432,16 @@ nsBaseChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +nsBaseChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsBaseChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsBaseChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) { nsCOMPtr loadGroup(mLoadGroup); diff --git a/netwerk/base/nsIRequest.idl b/netwerk/base/nsIRequest.idl index 49400771a632..1a831960bb8b 100644 --- a/netwerk/base/nsIRequest.idl +++ b/netwerk/base/nsIRequest.idl @@ -137,11 +137,68 @@ interface nsIRequest : nsISupports */ const unsigned long LOAD_DOCUMENT_NEEDS_COOKIE = 1 << 2; + cenum TRRMode : 8 { + TRR_DEFAULT_MODE = 0, + TRR_DISABLED_MODE = 1, + TRR_FIRST_MODE = 2, + TRR_ONLY_MODE = 3 + }; /** - * Set this flag to disable TRR for this request. + * These methods encode/decode the TRR mode to/from the loadFlags. + * Helper methods Get/SetTRRModeImpl are provided so implementations don't + * need to duplicate code. + * + * Requests with TRR_DEFAULT_MODE will use the mode indicated by the pref + * - see network.trr.mode in all.js + * Requests with TRR_DISABLED_MODE will always use native DNS, even if the + * pref is set to mode3 (TRR-only). + * Requests with TRR_DISABLED_MODE will first use TRR then fallback to + * regular DNS, unless TRR is disabled by setting the pref to mode5, + * parental control being enabled, or the domain being in the exclusion + * list. + * Requests with TRR_ONLY_MODE will only use TRR, unless not allowed by + * the same conditions mentioned above. */ - const unsigned long LOAD_DISABLE_TRR = 1 << 3; + nsIRequest_TRRMode getTRRMode(); + void setTRRMode(in nsIRequest_TRRMode mode); + + %{C++ + inline TRRMode GetTRRMode() { + TRRMode mode = TRR_DEFAULT_MODE; + GetTRRMode(&mode); + return mode; + } + + inline nsresult GetTRRModeImpl(nsIRequest::TRRMode* aTRRMode) { + NS_ENSURE_ARG_POINTER(aTRRMode); + nsLoadFlags flags = nsIRequest::LOAD_NORMAL; + nsresult rv = GetLoadFlags(&flags); + if (NS_FAILED(rv)) { + return rv; + } + *aTRRMode = static_cast( + (flags & nsIRequest::LOAD_TRR_MASK) >> 3); + return NS_OK; + } + + inline nsresult SetTRRModeImpl(nsIRequest::TRRMode aTRRMode) { + MOZ_ASSERT(aTRRMode <= 3, "invalid value"); + nsLoadFlags flags = nsIRequest::LOAD_NORMAL; + nsresult rv = GetLoadFlags(&flags); + if (NS_FAILED(rv)) { + return rv; + } + flags = (flags & ~nsIRequest::LOAD_TRR_MASK) | (aTRRMode << 3); + return SetLoadFlags(flags); + } + %} + + /** + * These two bits encode the TRR mode. + * Do not get/set manually, rather use the getTRRMode/setTRRMode methods. + */ + const unsigned long LOAD_TRR_MASK = (1 << 3) | (1 << 4); /************************************************************************** * The following flags control the flow of data into the cache. diff --git a/netwerk/base/nsISocketTransport.idl b/netwerk/base/nsISocketTransport.idl index 8f1b9698dd2a..a7576b01aeb9 100644 --- a/netwerk/base/nsISocketTransport.idl +++ b/netwerk/base/nsISocketTransport.idl @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsITransport.idl" +#include "nsIRequest.idl" interface nsIInterfaceRequestor; interface nsINetAddr; @@ -258,6 +259,23 @@ interface nsISocketTransport : nsITransport */ const unsigned long DONT_TRY_ESNI = (1 << 10); + /** + * These two bits encode the TRR mode of the request. + * Use the static helper methods convert between the TRR mode and flags. + */ + const unsigned long TRR_MODE_FLAGS = (1 << 11) | (1 << 12); + +%{C++ + + static uint32_t GetFlagsFromTRRMode(nsIRequest::TRRMode aMode) { + return static_cast(aMode) << 11; + } + + static nsIRequest::TRRMode GetTRRModeFromFlags(uint32_t aFlags) { + return static_cast((aFlags & TRR_MODE_FLAGS) >> 11); + } +%} + /** * An opaque flags for non-standard behavior of the TLS system. * It is unlikely this will need to be set outside of telemetry studies diff --git a/netwerk/base/nsIncrementalDownload.cpp b/netwerk/base/nsIncrementalDownload.cpp index f70141b7418e..fc2fcf5231f5 100644 --- a/netwerk/base/nsIncrementalDownload.cpp +++ b/netwerk/base/nsIncrementalDownload.cpp @@ -371,6 +371,16 @@ nsIncrementalDownload::SetLoadFlags(nsLoadFlags loadFlags) { return NS_OK; } +NS_IMETHODIMP +nsIncrementalDownload::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsIncrementalDownload::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsIncrementalDownload::GetLoadGroup(nsILoadGroup** loadGroup) { return NS_ERROR_NOT_IMPLEMENTED; diff --git a/netwerk/base/nsInputStreamPump.cpp b/netwerk/base/nsInputStreamPump.cpp index 789b68eddc27..543ad5e6585a 100644 --- a/netwerk/base/nsInputStreamPump.cpp +++ b/netwerk/base/nsInputStreamPump.cpp @@ -251,6 +251,16 @@ nsInputStreamPump::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +nsInputStreamPump::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsInputStreamPump::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsInputStreamPump::GetLoadGroup(nsILoadGroup** aLoadGroup) { RecursiveMutexAutoLock lock(mMutex); diff --git a/netwerk/base/nsLoadGroup.cpp b/netwerk/base/nsLoadGroup.cpp index c658f1a2b211..2685e747ebca 100644 --- a/netwerk/base/nsLoadGroup.cpp +++ b/netwerk/base/nsLoadGroup.cpp @@ -343,6 +343,16 @@ nsLoadGroup::SetLoadFlags(uint32_t aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +nsLoadGroup::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsLoadGroup::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsLoadGroup::GetLoadGroup(nsILoadGroup** loadGroup) { nsCOMPtr result = mLoadGroup; diff --git a/netwerk/base/nsSocketTransport2.cpp b/netwerk/base/nsSocketTransport2.cpp index 5f5c829fc591..b816634365e8 100644 --- a/netwerk/base/nsSocketTransport2.cpp +++ b/netwerk/base/nsSocketTransport2.cpp @@ -1039,6 +1039,9 @@ nsresult nsSocketTransport::ResolveHost() { if (mConnectionFlags & nsSocketTransport::DISABLE_TRR) dnsFlags |= nsIDNSService::RESOLVE_DISABLE_TRR; + dnsFlags |= nsIDNSService::GetFlagsFromTRRMode( + nsISocketTransport::GetTRRModeFromFlags(mConnectionFlags)); + NS_ASSERTION(!(dnsFlags & nsIDNSService::RESOLVE_DISABLE_IPV6) || !(dnsFlags & nsIDNSService::RESOLVE_DISABLE_IPV4), "Setting both RESOLVE_DISABLE_IPV6 and RESOLVE_DISABLE_IPV4"); diff --git a/netwerk/dns/TRR.cpp b/netwerk/dns/TRR.cpp index 2caa4763b208..82412bc4a0f1 100644 --- a/netwerk/dns/TRR.cpp +++ b/netwerk/dns/TRR.cpp @@ -173,8 +173,10 @@ nsresult TRR::SendHTTPRequest() { return NS_ERROR_FAILURE; } - if ((mType == TRRTYPE_A) || (mType == TRRTYPE_AAAA)) { + if (((mType == TRRTYPE_A) || (mType == TRRTYPE_AAAA)) && + mRec->EffectiveTRRMode() != nsIRequest::TRR_ONLY_MODE) { // let NS resolves skip the blacklist check + // we also don't check the blacklist for TRR only requests MOZ_ASSERT(mRec); if (gTRRService->IsTRRBlacklisted(mHost, mOriginSuffix, mPB, true)) { @@ -254,6 +256,10 @@ nsresult TRR::SendHTTPRequest() { return NS_ERROR_UNEXPECTED; } + // This connection should not use TRR + rv = httpChannel->SetTRRMode(nsIRequest::TRR_DISABLED_MODE); + NS_ENSURE_SUCCESS(rv, rv); + rv = httpChannel->SetRequestHeader( NS_LITERAL_CSTRING("Accept"), NS_LITERAL_CSTRING("application/dns-message"), false); diff --git a/netwerk/dns/TRRService.cpp b/netwerk/dns/TRRService.cpp index 5a7215d3af46..d81ed4426303 100644 --- a/netwerk/dns/TRRService.cpp +++ b/netwerk/dns/TRRService.cpp @@ -21,6 +21,8 @@ static const char kClearPrivateData[] = "clear-private-data"; static const char kPurge[] = "browser:purge-session-history"; static const char kDisableIpv6Pref[] = "network.dns.disableIPv6"; static const char kCaptivedetectCanonicalURL[] = "captivedetect.canonicalURL"; +static const char kPrefSkipTRRParentalControl[] = + "network.dns.skipTRR-when-parental-control-enabled"; #define TRR_PREF_PREFIX "network.trr." #define TRR_PREF(x) TRR_PREF_PREFIX x @@ -47,6 +49,7 @@ TRRService::TRRService() mCaptiveIsPassed(false), mUseGET(false), mDisableECS(true), + mSkipTRRWhenParentalControlEnabled(true), mDisableAfterFails(5), mPlatformDisabledTRR(false), mClearTRRBLStorage(false), @@ -80,6 +83,7 @@ nsresult TRRService::Init() { prefBranch->AddObserver(TRR_PREF_PREFIX, this, true); prefBranch->AddObserver(kDisableIpv6Pref, this, true); prefBranch->AddObserver(kCaptivedetectCanonicalURL, this, true); + prefBranch->AddObserver(kPrefSkipTRRParentalControl, this, true); } nsCOMPtr captivePortalService = do_GetService(NS_CAPTIVEPORTAL_CID); @@ -118,9 +122,13 @@ void TRRService::GetParentalControlEnabledInternal() { } } -bool TRRService::Enabled() { +bool TRRService::Enabled(nsIRequest::TRRMode aMode) { + if (mMode == MODE_TRROFF) { + return false; + } if (mConfirmationState == CONFIRM_INIT && - (!mWaitForCaptive || mCaptiveIsPassed || (mMode == MODE_TRRONLY))) { + (!mWaitForCaptive || mCaptiveIsPassed || + (mMode == MODE_TRRONLY || aMode == nsIRequest::TRR_ONLY_MODE))) { LOG(("TRRService::Enabled => CONFIRM_TRYING\n")); mConfirmationState = CONFIRM_TRYING; } @@ -347,6 +355,13 @@ nsresult TRRService::ReadPrefs(const char* name) { } } + if (!name || !strcmp(name, kPrefSkipTRRParentalControl)) { + bool tmp; + if (NS_SUCCEEDED(Preferences::GetBool(kPrefSkipTRRParentalControl, &tmp))) { + mSkipTRRWhenParentalControlEnabled = tmp; + } + } + // if name is null, then we're just now initializing. In that case we don't // need to clear the cache. if (name && clearEntireCache) { @@ -439,17 +454,20 @@ TRRService::Observe(nsISupports* aSubject, const char* aTopic, } } - if (!mCaptiveIsPassed) { - if (mConfirmationState != CONFIRM_OK) { - mConfirmationState = CONFIRM_TRYING; - MaybeConfirm(); + // We should avoid doing calling MaybeConfirm in response to a pref change + // unless the service is in a TRR=enabled mode. + if (mMode == MODE_TRRFIRST || mMode == MODE_TRRONLY) { + if (!mCaptiveIsPassed) { + if (mConfirmationState != CONFIRM_OK) { + mConfirmationState = CONFIRM_TRYING; + MaybeConfirm(); + } + } else { + LOG(("TRRservice CP clear when already up!\n")); } - } else { - LOG(("TRRservice CP clear when already up!\n")); + mCaptiveIsPassed = true; } - mCaptiveIsPassed = true; - } else if (!strcmp(aTopic, kClearPrivateData) || !strcmp(aTopic, kPurge)) { // flush the TRR blacklist, both in-memory and on-disk if (mTRRBLStorage) { @@ -506,7 +524,7 @@ void TRRService::MaybeConfirm() { void TRRService::MaybeConfirm_locked() { mLock.AssertCurrentThreadOwns(); - if (TRR_DISABLED(mMode) || mConfirmer || + if (mMode == MODE_TRROFF || mConfirmer || mConfirmationState != CONFIRM_TRYING) { LOG( ("TRRService:MaybeConfirm mode=%d, mConfirmer=%p " @@ -531,7 +549,7 @@ void TRRService::MaybeConfirm_locked() { bool TRRService::MaybeBootstrap(const nsACString& aPossible, nsACString& aResult) { MutexAutoLock lock(mLock); - if (TRR_DISABLED(mMode) || mBootstrapAddr.IsEmpty()) { + if (mMode == MODE_TRROFF || mBootstrapAddr.IsEmpty()) { return false; } @@ -564,7 +582,7 @@ bool TRRService::IsDomainBlacklisted(const nsACString& aHost, // Only use the Storage API on the main thread MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread(), "wrong thread"); - if (!Enabled()) { + if (!Enabled(nsIRequest::TRR_DEFAULT_MODE)) { return true; } diff --git a/netwerk/dns/TRRService.h b/netwerk/dns/TRRService.h index 808d83985dbe..03c143c13781 100644 --- a/netwerk/dns/TRRService.h +++ b/netwerk/dns/TRRService.h @@ -31,7 +31,7 @@ class TRRService : public nsIObserver, TRRService(); nsresult Init(); nsresult Start(); - bool Enabled(); + bool Enabled(nsIRequest::TRRMode aMode); uint32_t Mode() { return mMode; } bool AllowRFC1918() { return mRfc1918; } @@ -41,6 +41,9 @@ class TRRService : public nsIObserver, bool WaitForAllResponses() { return mWaitForAllResponses; } bool DisableIPv6() { return mDisableIPv6; } bool DisableECS() { return mDisableECS; } + bool SkipTRRWhenParentalControlEnabled() { + return mSkipTRRWhenParentalControlEnabled; + } nsresult GetURI(nsCString& result); nsresult GetCredentials(nsCString& result); uint32_t GetRequestTimeout(); @@ -103,6 +106,7 @@ class TRRService : public nsIObserver, Atomic mWaitForAllResponses; // Don't notify until all are in Atomic mDisableIPv6; // don't even try Atomic mDisableECS; // disable EDNS Client Subnet in requests + Atomic mSkipTRRWhenParentalControlEnabled; Atomic mDisableAfterFails; // this many fails in a row means failed TRR service Atomic mPlatformDisabledTRR; diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index 9693b704f491..97f657065010 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -152,8 +152,9 @@ static inline bool IsLowPriority(uint16_t flags) { // 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 // host record (i.e., the flags that are passed down to PR_GetAddrInfoByName). -#define RES_KEY_FLAGS(_f) \ - ((_f) & (nsHostResolver::RES_CANON_NAME | nsHostResolver::RES_DISABLE_TRR)) +#define RES_KEY_FLAGS(_f) \ + ((_f) & (nsHostResolver::RES_CANON_NAME | nsHostResolver::RES_DISABLE_TRR | \ + nsIDNSService::RESOLVE_TRR_MODE_MASK)) #define IS_ADDR_TYPE(_type) ((_type) == nsIDNSService::RESOLVE_TYPE_DEFAULT) #define IS_OTHER_TYPE(_type) ((_type) != nsIDNSService::RESOLVE_TYPE_DEFAULT) @@ -165,12 +166,7 @@ nsHostKey::nsHostKey(const nsACString& aHost, uint16_t aType, uint16_t aFlags, flags(aFlags), af(aAf), pb(aPb), - originSuffix(aOriginsuffix) { - if (TRR_DISABLED(gTRRService->Mode())) { - // When not using TRR, lookup all answers as TRR-disabled - flags |= nsHostResolver::RES_DISABLE_TRR; - } -} + originSuffix(aOriginsuffix) {} bool nsHostKey::operator==(const nsHostKey& other) const { return host == other.host && type == other.type && @@ -547,8 +543,6 @@ static const char kPrefGetTtl[] = "network.dns.get-ttl"; static const char kPrefNativeIsLocalhost[] = "network.dns.native-is-localhost"; static const char kPrefThreadIdleTime[] = "network.dns.resolver-thread-extra-idle-time-seconds"; -static const char kPrefSkipTRRParentalControl[] = - "network.dns.skipTRR-when-parental-control-enabled"; static bool sGetTtlEnabled = false; mozilla::Atomic gNativeIsLocalhost; @@ -578,7 +572,6 @@ nsHostResolver::nsHostResolver(uint32_t maxCacheEntries, mLock("nsHostResolver.mLock"), mIdleTaskCV(mLock, "nsHostResolver.mIdleTaskCV"), mEvictionQSize(0), - mSkipTRRWhenParentalControlEnabled(true), mShutdown(true), mNumIdleTasks(0), mActiveTaskCount(0), @@ -602,8 +595,6 @@ nsresult nsHostResolver::Init() { mShutdown = false; mNCS = NetworkConnectivityService::GetSingleton(); - mSkipTRRWhenParentalControlEnabled = - Preferences::GetBool(kPrefSkipTRRParentalControl, true); // The preferences probably haven't been loaded from the disk yet, so we // need to register a callback that will set up the experiment once they @@ -829,7 +820,7 @@ nsresult nsHostResolver::ResolveHost(const nsACString& aHost, uint16_t type, // By-Type requests use only TRR. If TRR is disabled we can return // immediately. - if (IS_OTHER_TYPE(type) && TRR_DISABLED(Mode())) { + if (IS_OTHER_TYPE(type) && Mode() == MODE_TRROFF) { return NS_ERROR_UNKNOWN_HOST; } @@ -1199,6 +1190,10 @@ nsresult nsHostResolver::TrrLookup_unlocked(nsHostRecord* rec, TRR* pushedTRR) { // returns error if no TRR resolve is issued // it is impt this is not called while a native lookup is going on nsresult nsHostResolver::TrrLookup(nsHostRecord* aRec, TRR* pushedTRR) { + if (Mode() == MODE_TRROFF) { + return NS_ERROR_UNKNOWN_HOST; + } + RefPtr rec(aRec); mLock.AssertCurrentThreadOwns(); @@ -1221,7 +1216,8 @@ nsresult nsHostResolver::TrrLookup(nsHostRecord* aRec, TRR* pushedTRR) { #endif MOZ_ASSERT(!rec->mResolving); - if (!gTRRService || !gTRRService->Enabled()) { + nsIRequest::TRRMode reqMode = rec->EffectiveTRRMode(); + if (!gTRRService || !gTRRService->Enabled(reqMode)) { LOG(("TrrLookup:: %s service not enabled\n", rec->host.get())); return NS_ERROR_UNKNOWN_HOST; } @@ -1382,6 +1378,49 @@ ResolverMode nsHostResolver::Mode() { return MODE_NATIVEONLY; } +nsIRequest::TRRMode nsHostRecord::TRRMode() { + return nsIDNSService::GetTRRModeFromFlags(flags); +} + +nsIRequest::TRRMode nsHostRecord::EffectiveTRRMode() { + // 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(host) || + (gTRRService->SkipTRRWhenParentalControlEnabled() && + gTRRService->ParentalControlEnabled()); + } + + nsIRequest::TRRMode aRequestMode = TRRMode(); + if (!gTRRService) { + return aRequestMode; + } + + ResolverMode aResolverMode = static_cast(gTRRService->Mode()); + + if (skipTRR || aResolverMode == MODE_TRROFF || + aRequestMode == nsIRequest::TRR_DISABLED_MODE || + (aRequestMode == nsIRequest::TRR_DEFAULT_MODE && + aResolverMode == MODE_NATIVEONLY)) { + return nsIRequest::TRR_DISABLED_MODE; + } + + if (aRequestMode == nsIRequest::TRR_DEFAULT_MODE && + aResolverMode == MODE_TRRFIRST) { + return nsIRequest::TRR_FIRST_MODE; + } + + if (aRequestMode == nsIRequest::TRR_DEFAULT_MODE && + aResolverMode == MODE_TRRONLY) { + return nsIRequest::TRR_ONLY_MODE; + } + + return aRequestMode; +} + // Kick-off a name resolve operation, using native resolver and/or TRR nsresult nsHostResolver::NameLookup(nsHostRecord* rec) { nsresult rv = NS_ERROR_UNKNOWN_HOST; @@ -1390,8 +1429,8 @@ nsresult nsHostResolver::NameLookup(nsHostRecord* rec) { return NS_OK; } - ResolverMode mode = rec->mResolverMode = Mode(); - MOZ_ASSERT(mode != MODE_RESERVED1); + rec->mResolverMode = Mode(); + MOZ_ASSERT(rec->mResolverMode != MODE_RESERVED1); if (rec->IsAddrRecord()) { RefPtr addrRec = do_QueryObject(rec); @@ -1406,30 +1445,15 @@ nsresult nsHostResolver::NameLookup(nsHostRecord* rec) { addrRec->mTrrAAAAUsed = AddrHostRecord::INIT; } - // 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(rec->host) || - (mSkipTRRWhenParentalControlEnabled && - gTRRService->ParentalControlEnabled()); - } - - if (rec->flags & RES_DISABLE_TRR) { - if (mode == MODE_TRRONLY && !skipTRR) { - return rv; - } - mode = MODE_NATIVEONLY; - } - - if (!TRR_DISABLED(mode) && !skipTRR) { + nsIRequest::TRRMode effectiveRequestMode = rec->EffectiveTRRMode(); + if (effectiveRequestMode != nsIRequest::TRR_DISABLED_MODE && + !((rec->flags & RES_DISABLE_TRR))) { rv = TrrLookup(rec); } - if (TRR_DISABLED(mode) || ((mode == MODE_TRRFIRST) && NS_FAILED(rv)) || - (mode == MODE_TRRONLY && skipTRR)) { + if (effectiveRequestMode == nsIRequest::TRR_DISABLED_MODE || + (effectiveRequestMode == nsIRequest::TRR_FIRST_MODE && + (rec->flags & RES_DISABLE_TRR) && NS_FAILED(rv))) { if (!rec->IsAddrRecord()) { return rv; } diff --git a/netwerk/dns/nsHostResolver.h b/netwerk/dns/nsHostResolver.h index 1ae9adb8963a..21b79f4877bd 100644 --- a/netwerk/dns/nsHostResolver.h +++ b/netwerk/dns/nsHostResolver.h @@ -81,6 +81,12 @@ class nsHostRecord : public mozilla::LinkedListElement>, return 0; } + // Returns the TRR mode encoded by the flags + nsIRequest::TRRMode TRRMode(); + // Returns a TRR mode that takes into account if the TRR service is disabled, + // parental controls are on, domain matches exclusion list, etc. + nsIRequest::TRRMode EffectiveTRRMode(); + protected: friend class nsHostResolver; @@ -551,7 +557,6 @@ class nsHostResolver : public nsISupports, public AHostResolver { PRTime mCreationTime; mozilla::TimeDuration mLongIdleTimeout; mozilla::TimeDuration mShortIdleTimeout; - bool mSkipTRRWhenParentalControlEnabled; RefPtr mResolverThreads; RefPtr mNCS; diff --git a/netwerk/dns/nsIDNSService.idl b/netwerk/dns/nsIDNSService.idl index cb1620b59eec..026d2426e6d3 100644 --- a/netwerk/dns/nsIDNSService.idl +++ b/netwerk/dns/nsIDNSService.idl @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" +#include "nsIRequest.idl" %{ C++ #include "mozilla/BasePrincipal.h" @@ -294,6 +295,22 @@ interface nsIDNSService : nsISupports */ const unsigned long RESOLVE_REFRESH_CACHE = (1 << 10); + /** + * These two bits encode the TRR mode of the request. + * Use the static helper methods convert between the TRR mode and flags. + */ + const unsigned long RESOLVE_TRR_MODE_MASK = (1 << 11) | (1 << 12); + +%{C++ + static uint32_t GetFlagsFromTRRMode(nsIRequest::TRRMode aMode) { + return static_cast(aMode) << 11; + } + + static nsIRequest::TRRMode GetTRRModeFromFlags(uint32_t aFlags) { + return static_cast((aFlags & RESOLVE_TRR_MODE_MASK) >> 11); + } +%} + /** * This ure dns request types that are currently supported. * RESOLVE_TYPE_DEFAULT is standard A/AAAA lookup diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index c8bc00550e9b..5ba2d2813651 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -612,6 +612,16 @@ NS_IMETHODIMP DocumentChannelChild::GetLoadFlags(nsLoadFlags* aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +DocumentChannelChild::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +DocumentChannelChild::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP DocumentChannelChild::SetLoadFlags(nsLoadFlags aLoadFlags) { mLoadFlags = aLoadFlags; return NS_OK; diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 8b517a8d000d..019808c04a98 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -333,7 +333,7 @@ struct HttpConnectionInfoCloneArgs uint32_t tlsFlags; bool isolated; bool isTrrServiceChannel; - bool trrDisabled; + uint8_t trrMode; bool isIPv4Disabled; bool isIPv6Disabled; nsCString topWindowOrigin; diff --git a/netwerk/protocol/http/ClassifierDummyChannel.cpp b/netwerk/protocol/http/ClassifierDummyChannel.cpp index 9c0b0dc22357..58778644fe51 100644 --- a/netwerk/protocol/http/ClassifierDummyChannel.cpp +++ b/netwerk/protocol/http/ClassifierDummyChannel.cpp @@ -296,6 +296,16 @@ ClassifierDummyChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) { return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +ClassifierDummyChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +ClassifierDummyChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP ClassifierDummyChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_ERROR_NOT_IMPLEMENTED; diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index f8efe85dae9b..aeadfe1bbecd 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -482,6 +482,16 @@ HttpBaseChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +HttpBaseChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +HttpBaseChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP HttpBaseChannel::SetDocshellUserAgentOverride() { // This sets the docshell specific user agent override diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 262c4f14f6f8..fb6790c666ab 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -139,6 +139,8 @@ class HttpBaseChannel : public nsHashPropertyBag, NS_IMETHOD SetLoadGroup(nsILoadGroup* aLoadGroup) override; NS_IMETHOD GetLoadFlags(nsLoadFlags* aLoadFlags) override; NS_IMETHOD SetLoadFlags(nsLoadFlags aLoadFlags) override; + NS_IMETHOD GetTRRMode(nsIRequest::TRRMode* aTRRMode) override; + NS_IMETHOD SetTRRMode(nsIRequest::TRRMode aTRRMode) override; NS_IMETHOD SetDocshellUserAgentOverride(); // nsIChannel diff --git a/netwerk/protocol/http/HttpTransactionChild.cpp b/netwerk/protocol/http/HttpTransactionChild.cpp index 9c49f38b83be..6e5e88e6ff14 100644 --- a/netwerk/protocol/http/HttpTransactionChild.cpp +++ b/netwerk/protocol/http/HttpTransactionChild.cpp @@ -85,7 +85,7 @@ HttpTransactionChild::DeserializeHttpConnectionInfoCloneArgs( cinfo->SetBeConservative(aInfoArgs.beConservative()); cinfo->SetTlsFlags(aInfoArgs.tlsFlags()); cinfo->SetIsTrrServiceChannel(aInfoArgs.isTrrServiceChannel()); - cinfo->SetTrrDisabled(aInfoArgs.trrDisabled()); + cinfo->SetTRRMode(static_cast(aInfoArgs.trrMode())); cinfo->SetIPv4Disabled(aInfoArgs.isIPv4Disabled()); cinfo->SetIPv6Disabled(aInfoArgs.isIPv6Disabled()); diff --git a/netwerk/protocol/http/HttpTransactionParent.cpp b/netwerk/protocol/http/HttpTransactionParent.cpp index 612e4fe6c849..c0912c1a72f8 100644 --- a/netwerk/protocol/http/HttpTransactionParent.cpp +++ b/netwerk/protocol/http/HttpTransactionParent.cpp @@ -105,7 +105,7 @@ void HttpTransactionParent::GetStructFromInfo( aArgs.tlsFlags() = aInfo->GetTlsFlags(); aArgs.isolated() = aInfo->GetIsolated(); aArgs.isTrrServiceChannel() = aInfo->GetIsTrrServiceChannel(); - aArgs.trrDisabled() = aInfo->GetTrrDisabled(); + aArgs.trrMode() = static_cast(aInfo->GetTRRMode()); aArgs.isIPv4Disabled() = aInfo->GetIPv4Disabled(); aArgs.isIPv6Disabled() = aInfo->GetIPv6Disabled(); aArgs.topWindowOrigin() = aInfo->GetTopWindowOrigin(); @@ -653,6 +653,18 @@ HttpTransactionParent::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +HttpTransactionParent::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + MOZ_ASSERT(false, "Should not be called."); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +HttpTransactionParent::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + MOZ_ASSERT(false, "Should not be called."); + return NS_ERROR_NOT_IMPLEMENTED; +} + void HttpTransactionParent::ActorDestroy(ActorDestroyReason aWhy) { LOG(("HttpTransactionParent::ActorDestroy [this=%p]\n", this)); if (aWhy != Deletion) { diff --git a/netwerk/protocol/http/NullHttpChannel.cpp b/netwerk/protocol/http/NullHttpChannel.cpp index e3efc90c0f98..9939366446a9 100644 --- a/netwerk/protocol/http/NullHttpChannel.cpp +++ b/netwerk/protocol/http/NullHttpChannel.cpp @@ -454,6 +454,16 @@ NullHttpChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) { return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +NullHttpChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +NullHttpChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP NullHttpChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_ERROR_NOT_IMPLEMENTED; diff --git a/netwerk/protocol/http/nsHttp.h b/netwerk/protocol/http/nsHttp.h index af63f669a282..7c68e2d8673f 100644 --- a/netwerk/protocol/http/nsHttp.h +++ b/netwerk/protocol/http/nsHttp.h @@ -111,10 +111,6 @@ const char kHttp3VersionHEX[] = "ff00000018"; // this is draft 24. // on ERROR_NET_RESET. #define NS_HTTP_CONNECTION_RESTARTABLE (1 << 13) -// Disallow name resolutions for this transaction to use TRR - primarily -// for use with TRR implementations themselves -#define NS_HTTP_DISABLE_TRR (1 << 14) - // Allow re-using a spdy/http2 connection with NS_HTTP_ALLOW_KEEPALIVE not set. // This is primarily used to allow connection sharing for websockets over http/2 // without accidentally allowing it for websockets not over http/2 @@ -131,6 +127,14 @@ const char kHttp3VersionHEX[] = "ff00000018"; // this is draft 24. // The connection should not use IPv6 #define NS_HTTP_DISABLE_IPV6 (1 << 18) +// Encodes the TRR mode. +#define NS_HTTP_TRR_MODE_MASK ((1 << 19) | (1 << 20)) + +#define NS_HTTP_TRR_FLAGS_FROM_MODE(x) ((static_cast(x) & 3) << 19) + +#define NS_HTTP_TRR_MODE_FROM_FLAGS(x) \ + (static_cast((((x)&NS_HTTP_TRR_MODE_MASK) >> 19) & 3)) + //----------------------------------------------------------------------------- // some default values //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 6b10672fae48..9bd5fa9fedd0 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -614,12 +614,10 @@ nsresult nsHttpChannel::ContinueOnBeforeConnect(bool aShouldUpgrade, } if (mIsTRRServiceChannel) { - mCaps |= NS_HTTP_LARGE_KEEPALIVE | NS_HTTP_DISABLE_TRR; + mCaps |= NS_HTTP_LARGE_KEEPALIVE; } - if (mLoadFlags & LOAD_DISABLE_TRR) { - mCaps |= NS_HTTP_DISABLE_TRR; - } + mCaps |= NS_HTTP_TRR_FLAGS_FROM_MODE(nsIRequest::GetTRRMode()); // Finalize ConnectionInfo flags before SpeculativeConnect mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0); @@ -630,7 +628,7 @@ nsresult nsHttpChannel::ContinueOnBeforeConnect(bool aShouldUpgrade, mBeConservative); mConnectionInfo->SetTlsFlags(mTlsFlags); mConnectionInfo->SetIsTrrServiceChannel(mIsTRRServiceChannel); - mConnectionInfo->SetTrrDisabled(mCaps & NS_HTTP_DISABLE_TRR); + mConnectionInfo->SetTRRMode(nsIRequest::GetTRRMode()); mConnectionInfo->SetIPv4Disabled(mCaps & NS_HTTP_DISABLE_IPV4); mConnectionInfo->SetIPv6Disabled(mCaps & NS_HTTP_DISABLE_IPV6); @@ -903,7 +901,7 @@ void nsHttpChannel::SpeculativeConnect() { Unused << gHttpHandler->SpeculativeConnect( mConnectionInfo, callbacks, - mCaps & (NS_HTTP_DISALLOW_SPDY | NS_HTTP_DISABLE_TRR | + mCaps & (NS_HTTP_DISALLOW_SPDY | NS_HTTP_TRR_MODE_MASK | NS_HTTP_DISABLE_IPV4 | NS_HTTP_DISABLE_IPV6)); } diff --git a/netwerk/protocol/http/nsHttpConnectionInfo.cpp b/netwerk/protocol/http/nsHttpConnectionInfo.cpp index 6f34ccbb76b6..110c23f85d60 100644 --- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp +++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp @@ -106,7 +106,7 @@ void nsHttpConnectionInfo::Init(const nsACString& host, int32_t port, mOriginAttributes = originAttributes; mTlsFlags = 0x0; mIsTrrServiceChannel = false; - mTrrDisabled = false; + mTRRMode = nsIRequest::TRR_DEFAULT_MODE; mIPv4Disabled = false; mIPv6Disabled = false; @@ -234,11 +234,13 @@ void nsHttpConnectionInfo::BuildHashKey() { mHashKey.AppendLiteral("}"); } - if (GetTrrDisabled()) { - // When connecting with TRR disabled, we enforce a separate connection + if (GetTRRMode() != nsIRequest::TRR_DEFAULT_MODE) { + // When connecting with another TRR mode, we enforce a separate connection // hashkey so that we also can trigger a fresh DNS resolver that then // doesn't use TRR as the previous connection might have. - mHashKey.AppendLiteral("[NOTRR]"); + mHashKey.AppendLiteral("[TRR:"); + mHashKey.AppendInt(GetTRRMode()); + mHashKey.AppendLiteral("]"); } if (GetIPv4Disabled()) { @@ -328,7 +330,7 @@ already_AddRefed nsHttpConnectionInfo::Clone() const { clone->SetBeConservative(GetBeConservative()); clone->SetTlsFlags(GetTlsFlags()); clone->SetIsTrrServiceChannel(GetIsTrrServiceChannel()); - clone->SetTrrDisabled(GetTrrDisabled()); + clone->SetTRRMode(GetTRRMode()); clone->SetIPv4Disabled(GetIPv4Disabled()); clone->SetIPv6Disabled(GetIPv6Disabled()); MOZ_ASSERT(clone->Equals(this)); @@ -354,7 +356,7 @@ void nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo** outCI) { clone->SetBeConservative(GetBeConservative()); clone->SetTlsFlags(GetTlsFlags()); clone->SetIsTrrServiceChannel(GetIsTrrServiceChannel()); - clone->SetTrrDisabled(GetTrrDisabled()); + clone->SetTRRMode(GetTRRMode()); clone->SetIPv4Disabled(GetIPv4Disabled()); clone->SetIPv6Disabled(GetIPv6Disabled()); @@ -381,9 +383,9 @@ nsresult nsHttpConnectionInfo::CreateWildCard(nsHttpConnectionInfo** outParam) { return NS_OK; } -void nsHttpConnectionInfo::SetTrrDisabled(bool aNoTrr) { - if (mTrrDisabled != aNoTrr) { - mTrrDisabled = aNoTrr; +void nsHttpConnectionInfo::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + if (mTRRMode != aTRRMode) { + mTRRMode = aTRRMode; RebuildHashKey(); } } diff --git a/netwerk/protocol/http/nsHttpConnectionInfo.h b/netwerk/protocol/http/nsHttpConnectionInfo.h index dc7badec59f1..0d59ab5faed0 100644 --- a/netwerk/protocol/http/nsHttpConnectionInfo.h +++ b/netwerk/protocol/http/nsHttpConnectionInfo.h @@ -150,10 +150,8 @@ class nsHttpConnectionInfo final : public ARefBase { } bool GetIsTrrServiceChannel() const { return mIsTrrServiceChannel; } - // SetTrrDisabled means don't use TRR to resolve host names for this - // connection - void SetTrrDisabled(bool aNoTrr); - bool GetTrrDisabled() const { return mTrrDisabled; } + void SetTRRMode(nsIRequest::TRRMode aTRRMode); + nsIRequest::TRRMode GetTRRMode() const { return mTRRMode; } void SetIPv4Disabled(bool aNoIPv4); bool GetIPv4Disabled() const { return mIPv4Disabled; } @@ -236,11 +234,11 @@ class nsHttpConnectionInfo final : public ARefBase { bool mUsingConnect; // if will use CONNECT with http proxy nsCString mNPNToken; OriginAttributes mOriginAttributes; + nsIRequest::TRRMode mTRRMode; uint32_t mTlsFlags; uint16_t mIsolated : 1; uint16_t mIsTrrServiceChannel : 1; - uint16_t mTrrDisabled : 1; uint16_t mIPv4Disabled : 1; uint16_t mIPv6Disabled : 1; diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 6e9ef20b213f..7468d0705007 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -4111,9 +4111,8 @@ nsresult nsHttpConnectionMgr::nsHalfOpenSocket::SetupStreams( uint32_t tmpFlags = 0; if (mCaps & NS_HTTP_REFRESH_DNS) tmpFlags = nsISocketTransport::BYPASS_CACHE; - if (mCaps & NS_HTTP_DISABLE_TRR) { - tmpFlags = nsISocketTransport::DISABLE_TRR; - } + tmpFlags |= nsISocketTransport::GetFlagsFromTRRMode( + NS_HTTP_TRR_MODE_FROM_FLAGS(mCaps)); if (mCaps & NS_HTTP_LOAD_ANONYMOUS) tmpFlags |= nsISocketTransport::ANONYMOUS_CONNECT; diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp index 647e452e6844..a7c697226292 100644 --- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp +++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp @@ -393,6 +393,16 @@ nsViewSourceChannel::SetLoadFlags(uint32_t aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +nsViewSourceChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return nsIViewSourceChannel::GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsViewSourceChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return nsIViewSourceChannel::SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsViewSourceChannel::GetContentType(nsACString& aContentType) { NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); diff --git a/netwerk/streamconv/converters/nsMultiMixedConv.cpp b/netwerk/streamconv/converters/nsMultiMixedConv.cpp index a847b643e31a..0061feb51b69 100644 --- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp +++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp @@ -203,6 +203,16 @@ nsPartChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +nsPartChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +nsPartChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsPartChannel::GetIsDocument(bool* aIsDocument) { return NS_GetIsDocumentChannel(this, aIsDocument); diff --git a/toolkit/components/alerts/AlertNotification.cpp b/toolkit/components/alerts/AlertNotification.cpp index f94b2d1451fe..858cf5bd27cf 100644 --- a/toolkit/components/alerts/AlertNotification.cpp +++ b/toolkit/components/alerts/AlertNotification.cpp @@ -288,8 +288,10 @@ nsresult AlertImageRequest::Start() { // Unfortunately, the PB loader checks the load group, and asserts if its // load context's PB flag isn't set. The fix is to pass the load group to // `nsIAlertNotification::loadImage`. - int32_t loadFlags = - mInPrivateBrowsing ? nsIRequest::LOAD_ANONYMOUS : nsIRequest::LOAD_NORMAL; + int32_t loadFlags = nsIRequest::LOAD_NORMAL; + if (mInPrivateBrowsing) { + loadFlags = nsIRequest::LOAD_ANONYMOUS; + } rv = il->LoadImageXPCOM( mURI, nullptr, nullptr, mPrincipal, nullptr, this, nullptr, loadFlags, diff --git a/toolkit/components/captivedetect/CaptiveDetect.jsm b/toolkit/components/captivedetect/CaptiveDetect.jsm index 507469aba269..c1e451c972c3 100644 --- a/toolkit/components/captivedetect/CaptiveDetect.jsm +++ b/toolkit/components/captivedetect/CaptiveDetect.jsm @@ -34,7 +34,7 @@ function URLFetcher(url, timeout) { // Prevent privacy leaks xhr.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS; // Use the system's resolver for this check - xhr.channel.loadFlags |= Ci.nsIRequest.LOAD_DISABLE_TRR; + xhr.channel.setTRRMode(Ci.nsIRequest.TRR_DISABLED_MODE); // We except this from being classified xhr.channel.loadFlags |= Ci.nsIChannel.LOAD_BYPASS_URL_CLASSIFIER; diff --git a/toolkit/components/extensions/webrequest/StreamFilterParent.cpp b/toolkit/components/extensions/webrequest/StreamFilterParent.cpp index 0b34d4109a44..063f1272dbc8 100644 --- a/toolkit/components/extensions/webrequest/StreamFilterParent.cpp +++ b/toolkit/components/extensions/webrequest/StreamFilterParent.cpp @@ -446,6 +446,16 @@ StreamFilterParent::SetLoadFlags(nsLoadFlags aLoadFlags) { return mChannel->SetLoadFlags(aLoadFlags); } +NS_IMETHODIMP +StreamFilterParent::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +StreamFilterParent::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + /***************************************************************************** * nsIStreamListener *****************************************************************************/ diff --git a/uriloader/exthandler/ExternalHelperAppParent.cpp b/uriloader/exthandler/ExternalHelperAppParent.cpp index 4d01f39cbaf3..e23a5f7e8278 100644 --- a/uriloader/exthandler/ExternalHelperAppParent.cpp +++ b/uriloader/exthandler/ExternalHelperAppParent.cpp @@ -279,6 +279,16 @@ ExternalHelperAppParent::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP +ExternalHelperAppParent::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP +ExternalHelperAppParent::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP ExternalHelperAppParent::GetIsDocument(bool* aIsDocument) { return NS_GetIsDocumentChannel(this, aIsDocument); diff --git a/uriloader/exthandler/nsExternalProtocolHandler.cpp b/uriloader/exthandler/nsExternalProtocolHandler.cpp index 43f5b2fb0fcd..ebdb1554533d 100644 --- a/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -236,6 +236,14 @@ NS_IMETHODIMP nsExtProtocolChannel::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; } +NS_IMETHODIMP nsExtProtocolChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { + return GetTRRModeImpl(aTRRMode); +} + +NS_IMETHODIMP nsExtProtocolChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { + return SetTRRModeImpl(aTRRMode); +} + NS_IMETHODIMP nsExtProtocolChannel::GetIsDocument(bool* aIsDocument) { return NS_GetIsDocumentChannel(this, aIsDocument); }