diff --git a/netwerk/dns/ChildDNSService.cpp b/netwerk/dns/ChildDNSService.cpp index 6933f7ba7608..d05fcd8f9a6d 100644 --- a/netwerk/dns/ChildDNSService.cpp +++ b/netwerk/dns/ChildDNSService.cpp @@ -44,6 +44,7 @@ already_AddRefed ChildDNSService::GetSingleton() { return nullptr; } gChildDNSService = new ChildDNSService(); + gChildDNSService->Init(); ClearOnShutdown(&gChildDNSService); } @@ -53,9 +54,7 @@ already_AddRefed ChildDNSService::GetSingleton() { NS_IMPL_ISUPPORTS(ChildDNSService, nsIDNSService, nsPIDNSService, nsIObserver) ChildDNSService::ChildDNSService() - : mFirstTime(true), - mDisablePrefetch(false), - mPendingRequestsLock("DNSPendingRequestsLock") { + : mPendingRequestsLock("DNSPendingRequestsLock") { MOZ_ASSERT_IF(nsIOService::UseSocketProcess(), XRE_IsContentProcess() || XRE_IsParentProcess()); MOZ_ASSERT_IF(!nsIOService::UseSocketProcess(), @@ -332,6 +331,14 @@ ChildDNSService::GetMyHostName(nsACString& result) { return NS_ERROR_NOT_AVAILABLE; } +NS_IMETHODIMP +ChildDNSService::GetODoHActivated(bool* aResult) { + NS_ENSURE_ARG(aResult); + + *aResult = mODoHActivated; + return NS_OK; +} + void ChildDNSService::NotifyRequestDone(DNSRequestSender* aDnsRequest) { // We need the original flags and listener for the pending requests hash. uint32_t originalFlags = aDnsRequest->mFlags & ~RESOLVE_OFFLINE; @@ -385,6 +392,12 @@ nsresult ChildDNSService::Init() { // If a manual proxy is in use, disable prefetch implicitly prefs->AddObserver("network.proxy.type", this, false); } + + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (observerService) { + observerService->AddObserver(this, "odoh-service-activated", false); + } } mDisablePrefetch = @@ -433,12 +446,13 @@ ChildDNSService::ResetExcludedSVCDomainName(const nsACString& aOwnerName) { NS_IMETHODIMP ChildDNSService::Observe(nsISupports* subject, const char* topic, const char16_t* data) { - // we are only getting called if a preference has changed. - NS_ASSERTION(strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0, - "unexpected observe call"); + if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { + // Reread prefs + Init(); + } else if (!strcmp(topic, "odoh-service-activated")) { + mODoHActivated = u"true"_ns.Equals(data); + } - // Reread prefs - Init(); return NS_OK; } diff --git a/netwerk/dns/ChildDNSService.h b/netwerk/dns/ChildDNSService.h index 4788b6c11d4d..84132a99625a 100644 --- a/netwerk/dns/ChildDNSService.h +++ b/netwerk/dns/ChildDNSService.h @@ -53,8 +53,9 @@ class ChildDNSService final : public nsPIDNSService, public nsIObserver { nsIDNSResolverInfo* aResolver, nsIDNSListener* aListener, nsresult aReason, const OriginAttributes& aOriginAttributes); - bool mFirstTime; - bool mDisablePrefetch; + bool mFirstTime = true; + bool mDisablePrefetch = false; + bool mODoHActivated = false; // We need to remember pending dns requests to be able to cancel them. nsClassHashtable>> diff --git a/netwerk/dns/ODoHService.cpp b/netwerk/dns/ODoHService.cpp index 773de0b1da2a..7bba161dec57 100644 --- a/netwerk/dns/ODoHService.cpp +++ b/netwerk/dns/ODoHService.cpp @@ -5,11 +5,13 @@ #include "ODoHService.h" +#include "mozilla/net/SocketProcessChild.h" #include "mozilla/Preferences.h" #include "mozilla/StaticPrefs_network.h" #include "nsIDNSService.h" #include "nsIDNSByTypeRecord.h" #include "nsIOService.h" +#include "nsIObserverService.h" #include "ODoH.h" #include "TRRService.h" #include "nsURLHelper.h" @@ -241,6 +243,31 @@ ODoHService::OnLookupComplete(nsICancelable* aRequest, nsIDNSRecord* aRec, mODoHConfigs.reset(); mODoHConfigs.emplace(std::move(configs)); + // Let observers know whether ODoHService is activated or not. + bool hasODoHConfigs = !mODoHConfigs->IsEmpty(); + auto task = [hasODoHConfigs]() { + MOZ_ASSERT(NS_IsMainThread()); + if (XRE_IsSocketProcess()) { + SocketProcessChild::GetSingleton()->SendODoHServiceActivated( + hasODoHConfigs); + } + + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + + if (observerService) { + observerService->NotifyObservers(nullptr, "odoh-service-activated", + hasODoHConfigs ? u"true" : u"false"); + } + }; + + if (NS_IsMainThread()) { + task(); + } else { + NS_DispatchToMainThread( + NS_NewRunnableFunction("ODoHService::Activated", std::move(task))); + } + if (!mPendingRequests.IsEmpty()) { nsTArray> requests = std::move(mPendingRequests); nsCOMPtr target = gTRRService->MainThreadOrTRRThread(); diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index 41658534c16f..c7808c1ba878 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -777,6 +777,7 @@ nsDNSService::Init() { observerService->AddObserver(this, "last-pb-context-exited", false); observerService->AddObserver(this, NS_NETWORK_LINK_TOPIC, false); observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); + observerService->AddObserver(this, "odoh-service-activated", false); } RefPtr res; @@ -1242,6 +1243,14 @@ nsDNSService::GetMyHostName(nsACString& result) { return NS_ERROR_FAILURE; } +NS_IMETHODIMP +nsDNSService::GetODoHActivated(bool* aResult) { + NS_ENSURE_ARG(aResult); + + *aResult = mODoHActivated; + return NS_OK; +} + NS_IMETHODIMP nsDNSService::Observe(nsISupports* subject, const char* topic, const char16_t* data) { @@ -1262,6 +1271,8 @@ nsDNSService::Observe(nsISupports* subject, const char* topic, } } else if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { Shutdown(); + } else if (!strcmp(topic, "odoh-service-activated")) { + mODoHActivated = u"true"_ns.Equals(data); } if (flushCache && mResolver) { diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h index 06e901ddbbe8..26218d921ceb 100644 --- a/netwerk/dns/nsDNSService2.h +++ b/netwerk/dns/nsDNSService2.h @@ -103,6 +103,7 @@ class nsDNSService final : public nsPIDNSService, uint32_t mResCacheExpiration; uint32_t mResCacheGrace; bool mResolverPrefsUpdated; + bool mODoHActivated = false; nsClassHashtable> mFailedSVCDomainNames; }; diff --git a/netwerk/dns/nsIDNSService.idl b/netwerk/dns/nsIDNSService.idl index a408fb0540d5..a4544a268638 100644 --- a/netwerk/dns/nsIDNSService.idl +++ b/netwerk/dns/nsIDNSService.idl @@ -243,6 +243,12 @@ interface nsIDNSService : nsISupports */ readonly attribute AUTF8String myHostName; + /** + * Returns true when we have valid ODoHConfigs to encrypt/decrypt oblivious + * DNS packets. + */ + readonly attribute boolean ODoHActivated; + /************************************************************************* * Listed below are the various flags that may be OR'd together to form * the aFlags parameter passed to asyncResolve() and resolve(). diff --git a/netwerk/ipc/PSocketProcess.ipdl b/netwerk/ipc/PSocketProcess.ipdl index 003883eb6e78..aadd8184c70e 100644 --- a/netwerk/ipc/PSocketProcess.ipdl +++ b/netwerk/ipc/PSocketProcess.ipdl @@ -128,6 +128,7 @@ parent: OriginAttributes aOriginAttributes, nsCString aRequestString) returns (bool aAccepted); + async ODoHServiceActivated(bool aActivated); child: async Init(SocketPorcessInitAttributes aAttributes); diff --git a/netwerk/ipc/SocketProcessParent.cpp b/netwerk/ipc/SocketProcessParent.cpp index 7e3e0ac63c13..7fafa9d5783f 100644 --- a/netwerk/ipc/SocketProcessParent.cpp +++ b/netwerk/ipc/SocketProcessParent.cpp @@ -22,6 +22,7 @@ #include "mozilla/TelemetryIPC.h" #include "nsIAppStartup.h" #include "nsIHttpActivityObserver.h" +#include "nsIObserverService.h" #include "nsNSSIOLayer.h" #include "PSMIPCCommon.h" #include "secerr.h" @@ -425,5 +426,17 @@ SocketProcessParent::RecvPRemoteLazyInputStreamConstructor( return IPC_OK(); } +mozilla::ipc::IPCResult SocketProcessParent::RecvODoHServiceActivated( + const bool& aActivated) { + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + + if (observerService) { + observerService->NotifyObservers(nullptr, "odoh-service-activated", + aActivated ? u"true" : u"false"); + } + return IPC_OK(); +} + } // namespace net } // namespace mozilla diff --git a/netwerk/ipc/SocketProcessParent.h b/netwerk/ipc/SocketProcessParent.h index 679ccefac509..f7f24567b86f 100644 --- a/netwerk/ipc/SocketProcessParent.h +++ b/netwerk/ipc/SocketProcessParent.h @@ -119,6 +119,8 @@ class SocketProcessParent final PRemoteLazyInputStreamParent* aActor, const nsID& aID, const uint64_t& aSize); + mozilla::ipc::IPCResult RecvODoHServiceActivated(const bool& aActivated); + private: SocketProcessHost* mHost; UniquePtr mMemoryReportRequest; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index b175a91599b7..15cc7bdbd414 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -7312,7 +7312,17 @@ nsHttpChannel::OnStartRequest(nsIRequest* request) { NS_SUCCEEDED(mStatus)); } - if (gTRRService && gTRRService->IsConfirmed()) { + if (StaticPrefs::network_trr_odoh_enabled()) { + nsCOMPtr dns = do_GetService(NS_DNSSERVICE_CONTRACTID); + bool ODoHActivated = false; + if (dns && NS_SUCCEEDED(dns->GetODoHActivated(&ODoHActivated)) && + ODoHActivated) { + Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_ONSTART_SUCCESS_ODOH, + NS_SUCCEEDED(mStatus)); + } + } else if (gTRRService && gTRRService->IsConfirmed()) { + // Note this telemetry probe is not working when DNS resolution is done in + // the socket process. Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_ONSTART_SUCCESS_TRR, TRRService::AutoDetectedKey(), NS_SUCCEEDED(mStatus)); } diff --git a/netwerk/test/unit/test_odoh.js b/netwerk/test/unit/test_odoh.js index 19ed00e3cd2d..2e63ddd5832b 100644 --- a/netwerk/test/unit/test_odoh.js +++ b/netwerk/test/unit/test_odoh.js @@ -171,6 +171,7 @@ add_task(async function testODoHQueryA() { inRecord.QueryInterface(Ci.nsIDNSAddrRecord); let answer = inRecord.getNextAddrAsString(); Assert.equal(answer, expectedIP); + Assert.ok(dns.ODoHActivated); }); add_task(async function testODoHQueryAAAA() { @@ -199,4 +200,5 @@ add_task(async function testODoHQueryAAAA() { inRecord.QueryInterface(Ci.nsIDNSAddrRecord); let answer = inRecord.getNextAddrAsString(); Assert.equal(answer, expectedIP); + Assert.ok(dns.ODoHActivated); }); diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index e6695b959f65..2530d10d1c0a 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -3159,6 +3159,15 @@ "bug_numbers": [1682552], "alert_emails": ["necko@mozilla.com", "kershaw@mozilla.com"] }, + "HTTP_CHANNEL_ONSTART_SUCCESS_ODOH" : { + "record_in_processes": ["main"], + "products": ["firefox"], + "expires_in_version": "never", + "kind": "boolean", + "description": "Successfully started HTTP channels when ODoH is enabled", + "bug_numbers": [1689987], + "alert_emails": ["necko@mozilla.com", "kershaw@mozilla.com"] + }, "HTTP_CONNECTION_ENTRY_CACHE_HIT_1" : { "record_in_processes": ["main", "content"], "products": ["firefox", "fennec"],