diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index f90ed66072db..1ad40dd65723 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -248,6 +248,7 @@ #include "mozilla/ipc/IdleSchedulerChild.h" #include "mozilla/ipc/MessageChannel.h" #include "mozilla/net/ChannelEventQueue.h" +#include "mozilla/net/ChildDNSService.h" #include "mozilla/net/CookieJarSettings.h" #include "mozilla/net/NeckoChannelParams.h" #include "mozilla/net/RequestContextService.h" @@ -2081,11 +2082,20 @@ void Document::AccumulatePageLoadTelemetry( return; } - nsCString http3Key; - nsCString http3WithPriorityKey; + nsAutoCString dnsKey("Native"); + nsAutoCString http3Key; + nsAutoCString http3WithPriorityKey; nsCOMPtr httpChannel = do_QueryInterface(GetChannel()); if (httpChannel) { + bool resolvedByTRR = false; + Unused << httpChannel->GetIsResolvedByTRR(&resolvedByTRR); + if (resolvedByTRR) { + RefPtr dnsServiceChild = + net::ChildDNSService::GetSingleton(); + dnsServiceChild->GetTRRDomain(dnsKey); + } + uint32_t major; uint32_t minor; if (NS_SUCCEEDED(httpChannel->GetResponseVersion(&major, &minor))) { @@ -2131,6 +2141,10 @@ void Document::AccumulatePageLoadTelemetry( navigationStart, firstContentfulComposite); } + Telemetry::AccumulateTimeDelta( + Telemetry::DNS_PERF_FIRST_CONTENTFUL_PAINT_MS, dnsKey, navigationStart, + firstContentfulComposite); + Telemetry::AccumulateTimeDelta( Telemetry::PERF_FIRST_CONTENTFUL_PAINT_FROM_RESPONSESTART_MS, responseStart, firstContentfulComposite); diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index b450f151fd1f..9977d00343fb 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -113,6 +113,7 @@ #include "mozilla/loader/ScriptCacheActors.h" #include "mozilla/media/MediaChild.h" #include "mozilla/net/CaptivePortalService.h" +#include "mozilla/net/ChildDNSService.h" #include "mozilla/net/CookieServiceChild.h" #include "mozilla/net/DocumentChannelChild.h" #include "mozilla/net/HttpChannelChild.h" @@ -685,7 +686,11 @@ mozilla::ipc::IPCResult ContentChild::RecvSetXPCOMProcessAttributes( InitXPCOM(std::move(aXPCOMInit), aInitialData, aIsReadyForBackgroundProcessing); InitGraphicsDeviceData(aXPCOMInit.contentDeviceData()); - + RefPtr dnsServiceChild = + dont_AddRef(net::ChildDNSService::GetSingleton()); + if (dnsServiceChild) { + dnsServiceChild->SetTRRDomain(aXPCOMInit.trrDomain()); + } return IPC_OK(); } diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index c63f9cccd736..99ea5f92a613 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -53,6 +53,8 @@ #include "mozilla/ipc/URIUtils.h" #include "gfxPlatform.h" #include "gfxPlatformFontList.h" +#include "nsDNSService2.h" +#include "nsPIDNSService.h" #include "mozilla/AntiTrackingUtils.h" #include "mozilla/AppShutdown.h" #include "mozilla/AutoRestore.h" @@ -163,6 +165,7 @@ #include "mozilla/net/NeckoParent.h" #include "mozilla/net/PCookieServiceParent.h" #include "mozilla/net/CookieKey.h" +#include "mozilla/net/TRRService.h" #include "mozilla/TelemetryComms.h" #include "mozilla/TelemetryEventEnums.h" #include "mozilla/RemoteLazyInputStreamParent.h" @@ -3086,6 +3089,8 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) { xpcomInit.perfStatsMask() = PerfStats::GetCollectionMask(); + xpcomInit.trrDomain() = TRRService::ProviderKey(); + Unused << SendSetXPCOMProcessAttributes( xpcomInit, initialData, lnf, fontList, std::move(sharedUASheetHandle), sharedUASheetAddress, std::move(sharedFontListBlocks), diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 8c128a50c57f..301bd93eb97b 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -364,6 +364,7 @@ struct XPCOMInitData L10nFileSourceDescriptor[] l10nFileSources; DynamicScalarDefinition[] dynamicScalarDefs; MetricMask perfStatsMask; + nsCString trrDomain; }; struct VisitedQueryResult diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 3bc62bd117dc..e8f4443866ad 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -206,6 +206,7 @@ LOCAL_INCLUDES += [ "/layout/base", "/media/webrtc", "/netwerk/base", + "/netwerk/dns", "/netwerk/protocol/http", "/toolkit/components/printingui/ipc", "/toolkit/crashreporter", diff --git a/netwerk/dns/ChildDNSService.cpp b/netwerk/dns/ChildDNSService.cpp index f450d351b117..af2988a0200d 100644 --- a/netwerk/dns/ChildDNSService.cpp +++ b/netwerk/dns/ChildDNSService.cpp @@ -460,5 +460,13 @@ ChildDNSService::Observe(nsISupports* subject, const char* topic, return NS_OK; } +void ChildDNSService::SetTRRDomain(const nsACString& aTRRDomain) { + mTRRDomain = aTRRDomain; +} + +void ChildDNSService::GetTRRDomain(nsACString& aTRRDomain) { + aTRRDomain = mTRRDomain; +} + } // namespace net } // namespace mozilla diff --git a/netwerk/dns/ChildDNSService.h b/netwerk/dns/ChildDNSService.h index 8d53286809a7..3bd9ce040b56 100644 --- a/netwerk/dns/ChildDNSService.h +++ b/netwerk/dns/ChildDNSService.h @@ -35,6 +35,9 @@ class ChildDNSService final : public DNSServiceBase, public nsPIDNSService { void NotifyRequestDone(DNSRequestSender* aDnsRequest); + void SetTRRDomain(const nsACString& aTRRDomain); + void GetTRRDomain(nsACString& aTRRDomain); + private: virtual ~ChildDNSService() = default; @@ -60,6 +63,8 @@ class ChildDNSService final : public DNSServiceBase, public nsPIDNSService { mPendingRequests; Mutex mPendingRequestsLock MOZ_UNANNOTATED{"DNSPendingRequestsLock"}; RefPtr mTRRServiceParent; + + nsCString mTRRDomain; }; } // namespace net diff --git a/netwerk/dns/TRRService.cpp b/netwerk/dns/TRRService.cpp index 602fa13ceae0..940a150a57a1 100644 --- a/netwerk/dns/TRRService.cpp +++ b/netwerk/dns/TRRService.cpp @@ -23,6 +23,8 @@ #include "mozilla/Telemetry.h" #include "mozilla/TelemetryComms.h" #include "mozilla/Tokenizer.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/net/NeckoParent.h" #include "mozilla/net/TRRServiceChild.h" // Put DNSLogging.h at the end to avoid LOG being overwritten by other headers. #include "DNSLogging.h" @@ -300,6 +302,17 @@ bool TRRService::MaybeSetPrivateURI(const nsACString& aURI) { mPrivateURI = newURI; + // Notify the content processes of the new TRR + for (auto* cp : + dom::ContentParent::AllProcesses(dom::ContentParent::eLive)) { + PNeckoParent* neckoParent = + SingleManagedOrNull(cp->ManagedPNeckoParent()); + if (!neckoParent) { + continue; + } + Unused << neckoParent->SendSetTRRDomain(ProviderKey()); + } + AsyncCreateTRRConnectionInfo(mPrivateURI); // The URI has changed. We should trigger a new confirmation immediately. diff --git a/netwerk/dns/moz.build b/netwerk/dns/moz.build index 5d81059ed89d..3538707f7e57 100644 --- a/netwerk/dns/moz.build +++ b/netwerk/dns/moz.build @@ -42,6 +42,7 @@ EXPORTS.mozilla.net += [ "DNSRequestBase.h", "DNSRequestChild.h", "DNSRequestParent.h", + "DNSServiceBase.h", "HTTPSSVC.h", "IDNBlocklistUtils.h", "NativeDNSResolverOverrideChild.h", diff --git a/netwerk/ipc/NeckoChild.cpp b/netwerk/ipc/NeckoChild.cpp index 2a1b2909a2e8..ead16ef1716c 100644 --- a/netwerk/ipc/NeckoChild.cpp +++ b/netwerk/ipc/NeckoChild.cpp @@ -10,6 +10,7 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/BrowserChild.h" #include "mozilla/net/HttpChannelChild.h" +#include "mozilla/net/ChildDNSService.h" #include "mozilla/net/CookieServiceChild.h" #include "mozilla/net/DataChannelChild.h" #ifdef MOZ_WIDGET_GTK @@ -343,5 +344,14 @@ bool NeckoChild::DeallocPClassifierDummyChannelChild( return true; } +mozilla::ipc::IPCResult NeckoChild::RecvSetTRRDomain(const nsCString& domain) { + RefPtr dnsServiceChild = + dont_AddRef(net::ChildDNSService::GetSingleton()); + if (dnsServiceChild) { + dnsServiceChild->SetTRRDomain(domain); + } + return IPC_OK(); +} + } // namespace net } // namespace mozilla diff --git a/netwerk/ipc/NeckoChild.h b/netwerk/ipc/NeckoChild.h index 7c9d43d25126..18d140de5595 100644 --- a/netwerk/ipc/NeckoChild.h +++ b/netwerk/ipc/NeckoChild.h @@ -84,6 +84,8 @@ class NeckoChild : public PNeckoChild { bool DeallocPClassifierDummyChannelChild( PClassifierDummyChannelChild* aActor); + + mozilla::ipc::IPCResult RecvSetTRRDomain(const nsCString& domain); }; /** diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl index c250a681fdf3..1be75ec4d13a 100644 --- a/netwerk/ipc/PNecko.ipdl +++ b/netwerk/ipc/PNecko.ipdl @@ -166,6 +166,8 @@ child: async PTransportProvider(); + async SetTRRDomain(nsCString domain); + both: // Actually we need PTCPSocket() for parent. But ipdl disallows us having different // signatures on parent and child. So when constructing the parent side object, we just diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 5807ce70c606..4cea16129586 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -5243,6 +5243,19 @@ "kind": "enumerated", "description": "The reason why we failed to connect with an HTTPSSVC record" }, + "DNS_PERF_FIRST_CONTENTFUL_PAINT_MS": { + "record_in_processes": ["content"], + "products": ["firefox"], + "alert_emails": ["necko@mozilla.com", "acreskey@mozilla.com"], + "expires_in_version": "never", + "releaseChannelCollection": "opt-out", + "kind": "exponential", + "high": 50000, + "n_buckets": 100, + "bug_numbers": [1796639], + "keyed": true, + "description": "The time between navigationStart and the first contentful paint of a foreground http or https root content document, in milliseconds. The contentful paint timestamp is taken during display list building and does not include rasterization or compositing of that paint. Keyed by TRR domain for DoH or 'Native' otherwise" + }, "REFRESH_DRIVER_TICK" : { "record_in_processes": ["main", "content"], "products": ["firefox", "fennec"],