Bug 1900094 - Add telemetry for impressions missing due to domain-to-categories map...
[gecko.git] / netwerk / ipc / SocketProcessChild.cpp
blobe23653f8603230f479b778b9973dce9ec14de11d
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "SocketProcessChild.h"
7 #include "SocketProcessLogging.h"
9 #include "base/task.h"
10 #include "InputChannelThrottleQueueChild.h"
11 #include "HttpInfo.h"
12 #include "HttpTransactionChild.h"
13 #include "HttpConnectionMgrChild.h"
14 #include "mozilla/Assertions.h"
15 #include "mozilla/Atomics.h"
16 #include "mozilla/Components.h"
17 #include "mozilla/dom/MemoryReportRequest.h"
18 #include "mozilla/FOGIPC.h"
19 #include "mozilla/glean/GleanMetrics.h"
20 #include "mozilla/ipc/CrashReporterClient.h"
21 #include "mozilla/ipc/ProcessChild.h"
22 #include "mozilla/net/AltSvcTransactionChild.h"
23 #include "mozilla/net/BackgroundDataBridgeParent.h"
24 #include "mozilla/net/DNSRequestChild.h"
25 #include "mozilla/net/DNSRequestParent.h"
26 #include "mozilla/net/NativeDNSResolverOverrideChild.h"
27 #include "mozilla/net/ProxyAutoConfigChild.h"
28 #include "mozilla/net/SocketProcessBackgroundChild.h"
29 #include "mozilla/net/TRRServiceChild.h"
30 #include "mozilla/ipc/ProcessUtils.h"
31 #include "mozilla/Preferences.h"
32 #include "mozilla/RemoteLazyInputStreamChild.h"
33 #include "mozilla/StaticPrefs_javascript.h"
34 #include "mozilla/StaticPrefs_network.h"
35 #include "mozilla/Telemetry.h"
36 #include "NetworkConnectivityService.h"
37 #include "nsDebugImpl.h"
38 #include "nsHttpConnectionInfo.h"
39 #include "nsHttpHandler.h"
40 #include "nsIDNSService.h"
41 #include "nsIHttpActivityObserver.h"
42 #include "nsIXULRuntime.h"
43 #include "nsNetUtil.h"
44 #include "nsNSSComponent.h"
45 #include "nsSocketTransportService2.h"
46 #include "nsThreadManager.h"
47 #include "SocketProcessBridgeParent.h"
48 #include "jsapi.h"
49 #include "js/Initialization.h"
50 #include "js/Prefs.h"
51 #include "XPCSelfHostedShmem.h"
53 #if defined(XP_WIN)
54 # include <process.h>
56 # include "mozilla/WinDllServices.h"
57 #else
58 # include <unistd.h>
59 #endif
61 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
62 # include "mozilla/Sandbox.h"
63 # include "mozilla/SandboxProfilerObserver.h"
64 #endif
66 #include "ChildProfilerController.h"
68 #ifdef MOZ_WEBRTC
69 # include "mozilla/net/WebrtcTCPSocketChild.h"
70 #endif
72 #if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
73 # include "mozilla/SandboxTestingChild.h"
74 #endif
76 namespace mozilla {
77 namespace net {
79 using namespace ipc;
81 static bool sInitializedJS = false;
83 static Atomic<SocketProcessChild*> sSocketProcessChild;
85 SocketProcessChild::SocketProcessChild() {
86 LOG(("CONSTRUCT SocketProcessChild::SocketProcessChild\n"));
87 nsDebugImpl::SetMultiprocessMode("Socket");
89 MOZ_COUNT_CTOR(SocketProcessChild);
90 sSocketProcessChild = this;
93 SocketProcessChild::~SocketProcessChild() {
94 LOG(("DESTRUCT SocketProcessChild::SocketProcessChild\n"));
95 MOZ_COUNT_DTOR(SocketProcessChild);
96 sSocketProcessChild = nullptr;
99 /* static */
100 SocketProcessChild* SocketProcessChild::GetSingleton() {
101 return sSocketProcessChild;
104 #if defined(XP_MACOSX)
105 extern "C" {
106 void CGSShutdownServerConnections();
108 #endif
110 void SocketProcessChild::InitSocketBackground() {
111 Endpoint<PSocketProcessBackgroundParent> parentEndpoint;
112 Endpoint<PSocketProcessBackgroundChild> childEndpoint;
113 if (NS_WARN_IF(NS_FAILED(PSocketProcessBackground::CreateEndpoints(
114 &parentEndpoint, &childEndpoint)))) {
115 return;
118 SocketProcessBackgroundChild::Create(std::move(childEndpoint));
120 Unused << SendInitSocketBackground(std::move(parentEndpoint));
123 namespace {
125 class NetTeardownObserver final : public nsIObserver {
126 public:
127 NetTeardownObserver() = default;
129 NS_DECL_ISUPPORTS
130 NS_DECL_NSIOBSERVER
132 private:
133 ~NetTeardownObserver() = default;
136 NS_IMPL_ISUPPORTS(NetTeardownObserver, nsIObserver)
138 NS_IMETHODIMP
139 NetTeardownObserver::Observe(nsISupports* aSubject, const char* aTopic,
140 const char16_t* aData) {
141 if (SocketProcessChild* child = SocketProcessChild::GetSingleton()) {
142 child->CloseIPCClientCertsActor();
145 return NS_OK;
148 } // namespace
150 bool SocketProcessChild::Init(mozilla::ipc::UntypedEndpoint&& aEndpoint,
151 const char* aParentBuildID) {
152 if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) {
153 return false;
155 if (NS_WARN_IF(!aEndpoint.Bind(this))) {
156 return false;
158 // This must be sent before any IPDL message, which may hit sentinel
159 // errors due to parent and content processes having different
160 // versions.
161 MessageChannel* channel = GetIPCChannel();
162 if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) {
163 // We need to quit this process if the buildID doesn't match the parent's.
164 // This can occur when an update occurred in the background.
165 ProcessChild::QuickExit();
168 // Init crash reporter support.
169 CrashReporterClient::InitSingleton(this);
171 if (NS_FAILED(NS_InitMinimalXPCOM())) {
172 return false;
175 InitSocketBackground();
177 SetThisProcessName("Socket Process");
178 #if defined(XP_MACOSX)
179 // Close all current connections to the WindowServer. This ensures that the
180 // Activity Monitor will not label the socket process as "Not responding"
181 // because it's not running a native event loop. See bug 1384336.
182 CGSShutdownServerConnections();
183 #endif // XP_MACOSX
185 nsresult rv;
186 nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv);
187 if (NS_FAILED(rv)) {
188 return false;
191 nsCOMPtr<nsIProtocolHandler> handler;
192 rv = ios->GetProtocolHandler("http", getter_AddRefs(handler));
193 if (NS_FAILED(rv)) {
194 return false;
197 // Initialize DNS Service here, since it needs to be done in main thread.
198 mozilla::components::DNS::Service(&rv);
199 if (NS_FAILED(rv)) {
200 return false;
203 if (!EnsureNSSInitializedChromeOrContent()) {
204 return false;
207 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
208 if (obs) {
209 nsCOMPtr<nsIObserver> observer = new NetTeardownObserver();
210 Unused << obs->AddObserver(observer, "profile-change-net-teardown", false);
213 mSocketThread = mozilla::components::SocketTransport::Service();
214 if (!mSocketThread) {
215 return false;
218 return true;
221 void SocketProcessChild::ActorDestroy(ActorDestroyReason aWhy) {
222 LOG(("SocketProcessChild::ActorDestroy\n"));
225 MutexAutoLock lock(mMutex);
226 mShuttingDown = true;
229 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
230 DestroySandboxProfiler();
231 #endif
233 if (AbnormalShutdown == aWhy) {
234 NS_WARNING("Shutting down Socket process early due to a crash!");
235 ProcessChild::QuickExit();
238 // Send the last bits of Glean data over to the main process.
239 glean::FlushFOGData(
240 [](ByteBuf&& aBuf) { glean::SendFOGData(std::move(aBuf)); });
242 if (mProfilerController) {
243 mProfilerController->Shutdown();
244 mProfilerController = nullptr;
247 CrashReporterClient::DestroySingleton();
248 XRE_ShutdownChildProcess();
251 void SocketProcessChild::CleanUp() {
252 LOG(("SocketProcessChild::CleanUp\n"));
254 SocketProcessBackgroundChild::Shutdown();
256 for (const auto& parent : mSocketProcessBridgeParentMap.Values()) {
257 if (parent->CanSend()) {
258 parent->Close();
263 MutexAutoLock lock(mMutex);
264 mBackgroundDataBridgeMap.Clear();
267 // Normally, the IPC channel should be already closed at this point, but
268 // sometimes it's not (bug 1788860). When the channel is closed, calling
269 // Close() again is harmless.
270 Close();
272 NS_ShutdownXPCOM(nullptr);
274 if (sInitializedJS) {
275 JS_ShutDown();
279 mozilla::ipc::IPCResult SocketProcessChild::RecvInit(
280 const SocketPorcessInitAttributes& aAttributes) {
281 Unused << RecvSetOffline(aAttributes.mOffline());
282 Unused << RecvSetConnectivity(aAttributes.mConnectivity());
283 if (aAttributes.mInitSandbox()) {
284 Unused << RecvInitLinuxSandbox(aAttributes.mSandboxBroker());
287 #if defined(XP_WIN)
288 RefPtr<DllServices> dllSvc(DllServices::Get());
289 dllSvc->StartUntrustedModulesProcessor(
290 aAttributes.mIsReadyForBackgroundProcessing());
291 #endif // defined(XP_WIN)
293 return IPC_OK();
296 IPCResult SocketProcessChild::RecvPreferenceUpdate(const Pref& aPref) {
297 Preferences::SetPreference(aPref);
298 return IPC_OK();
301 mozilla::ipc::IPCResult SocketProcessChild::RecvRequestMemoryReport(
302 const uint32_t& aGeneration, const bool& aAnonymize,
303 const bool& aMinimizeMemoryUsage,
304 const Maybe<ipc::FileDescriptor>& aDMDFile,
305 const RequestMemoryReportResolver& aResolver) {
306 nsPrintfCString processName("Socket (pid %u)", (unsigned)getpid());
308 mozilla::dom::MemoryReportRequestClient::Start(
309 aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName,
310 [&](const MemoryReport& aReport) {
311 Unused << GetSingleton()->SendAddMemoryReport(aReport);
313 aResolver);
314 return IPC_OK();
317 mozilla::ipc::IPCResult SocketProcessChild::RecvSetOffline(
318 const bool& aOffline) {
319 LOG(("SocketProcessChild::RecvSetOffline aOffline=%d\n", aOffline));
321 nsCOMPtr<nsIIOService> io(do_GetIOService());
322 NS_ASSERTION(io, "IO Service can not be null");
324 io->SetOffline(aOffline);
326 return IPC_OK();
329 mozilla::ipc::IPCResult SocketProcessChild::RecvSetConnectivity(
330 const bool& aConnectivity) {
331 nsCOMPtr<nsIIOService> io(do_GetIOService());
332 nsCOMPtr<nsIIOServiceInternal> ioInternal(do_QueryInterface(io));
333 NS_ASSERTION(ioInternal, "IO Service can not be null");
335 ioInternal->SetConnectivity(aConnectivity);
337 return IPC_OK();
340 mozilla::ipc::IPCResult SocketProcessChild::RecvInitLinuxSandbox(
341 const Maybe<ipc::FileDescriptor>& aBrokerFd) {
342 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
343 int fd = -1;
344 if (aBrokerFd.isSome()) {
345 fd = aBrokerFd.value().ClonePlatformHandle().release();
347 RegisterProfilerObserversForSandboxProfiler();
348 SetSocketProcessSandbox(fd);
349 #endif // XP_LINUX && MOZ_SANDBOX
350 return IPC_OK();
353 mozilla::ipc::IPCResult SocketProcessChild::RecvInitSocketProcessBridgeParent(
354 const ProcessId& aContentProcessId,
355 Endpoint<mozilla::net::PSocketProcessBridgeParent>&& aEndpoint) {
356 MOZ_ASSERT(NS_IsMainThread());
357 MOZ_ASSERT(!mSocketProcessBridgeParentMap.Contains(aContentProcessId));
359 if (NS_WARN_IF(!aEndpoint.IsValid())) {
360 return IPC_FAIL(this, "invalid endpoint");
363 auto bridge = MakeRefPtr<SocketProcessBridgeParent>(aContentProcessId);
364 MOZ_ALWAYS_TRUE(aEndpoint.Bind(bridge));
366 mSocketProcessBridgeParentMap.InsertOrUpdate(aContentProcessId,
367 std::move(bridge));
368 return IPC_OK();
371 mozilla::ipc::IPCResult SocketProcessChild::RecvInitProfiler(
372 Endpoint<PProfilerChild>&& aEndpoint) {
373 mProfilerController =
374 mozilla::ChildProfilerController::Create(std::move(aEndpoint));
375 return IPC_OK();
378 #if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
379 mozilla::ipc::IPCResult SocketProcessChild::RecvInitSandboxTesting(
380 Endpoint<PSandboxTestingChild>&& aEndpoint) {
381 if (!SandboxTestingChild::Initialize(std::move(aEndpoint))) {
382 return IPC_FAIL(
383 this, "InitSandboxTesting failed to initialise the child process.");
385 return IPC_OK();
387 #endif
389 mozilla::ipc::IPCResult SocketProcessChild::RecvSocketProcessTelemetryPing() {
390 const uint32_t kExpectedUintValue = 42;
391 Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_SOCKET_ONLY_UINT,
392 kExpectedUintValue);
393 return IPC_OK();
396 void SocketProcessChild::DestroySocketProcessBridgeParent(ProcessId aId) {
397 MOZ_ASSERT(NS_IsMainThread());
399 mSocketProcessBridgeParentMap.Remove(aId);
402 PWebrtcTCPSocketChild* SocketProcessChild::AllocPWebrtcTCPSocketChild(
403 const Maybe<TabId>& tabId) {
404 // We don't allocate here: instead we always use IPDL constructor that takes
405 // an existing object
406 MOZ_ASSERT_UNREACHABLE(
407 "AllocPWebrtcTCPSocketChild should not be called on"
408 " socket child");
409 return nullptr;
412 bool SocketProcessChild::DeallocPWebrtcTCPSocketChild(
413 PWebrtcTCPSocketChild* aActor) {
414 #ifdef MOZ_WEBRTC
415 WebrtcTCPSocketChild* child = static_cast<WebrtcTCPSocketChild*>(aActor);
416 child->ReleaseIPDLReference();
417 #endif
418 return true;
421 already_AddRefed<PHttpTransactionChild>
422 SocketProcessChild::AllocPHttpTransactionChild() {
423 RefPtr<HttpTransactionChild> actor = new HttpTransactionChild();
424 return actor.forget();
427 already_AddRefed<PHttpConnectionMgrChild>
428 SocketProcessChild::AllocPHttpConnectionMgrChild(
429 const HttpHandlerInitArgs& aArgs) {
430 LOG(("SocketProcessChild::AllocPHttpConnectionMgrChild \n"));
431 MOZ_ASSERT(gHttpHandler);
432 gHttpHandler->SetHttpHandlerInitArgs(aArgs);
434 RefPtr<HttpConnectionMgrChild> actor = new HttpConnectionMgrChild();
435 return actor.forget();
438 mozilla::ipc::IPCResult SocketProcessChild::RecvUpdateDeviceModelId(
439 const nsACString& aModelId) {
440 MOZ_ASSERT(gHttpHandler);
441 gHttpHandler->SetDeviceModelId(aModelId);
442 return IPC_OK();
445 mozilla::ipc::IPCResult
446 SocketProcessChild::RecvOnHttpActivityDistributorActivated(
447 const bool& aIsActivated) {
448 nsCOMPtr<nsIHttpActivityObserver> distributor;
449 distributor = mozilla::components::HttpActivityDistributor::Service();
450 if (distributor) {
451 distributor->SetIsActive(aIsActivated);
453 return IPC_OK();
456 mozilla::ipc::IPCResult
457 SocketProcessChild::RecvOnHttpActivityDistributorObserveProxyResponse(
458 const bool& aIsEnabled) {
459 nsCOMPtr<nsIHttpActivityDistributor> distributor;
460 distributor = mozilla::components::HttpActivityDistributor::Service();
461 if (distributor) {
462 Unused << distributor->SetObserveProxyResponse(aIsEnabled);
464 return IPC_OK();
467 mozilla::ipc::IPCResult
468 SocketProcessChild::RecvOnHttpActivityDistributorObserveConnection(
469 const bool& aIsEnabled) {
470 nsCOMPtr<nsIHttpActivityDistributor> distributor;
471 distributor = mozilla::components::HttpActivityDistributor::Service();
472 if (distributor) {
473 Unused << distributor->SetObserveConnection(aIsEnabled);
475 return IPC_OK();
478 already_AddRefed<PInputChannelThrottleQueueChild>
479 SocketProcessChild::AllocPInputChannelThrottleQueueChild(
480 const uint32_t& aMeanBytesPerSecond, const uint32_t& aMaxBytesPerSecond) {
481 RefPtr<InputChannelThrottleQueueChild> p =
482 new InputChannelThrottleQueueChild();
483 p->Init(aMeanBytesPerSecond, aMaxBytesPerSecond);
484 return p.forget();
487 already_AddRefed<PAltSvcTransactionChild>
488 SocketProcessChild::AllocPAltSvcTransactionChild(
489 const HttpConnectionInfoCloneArgs& aConnInfo, const uint32_t& aCaps) {
490 RefPtr<nsHttpConnectionInfo> cinfo =
491 nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(aConnInfo);
492 RefPtr<AltSvcTransactionChild> child =
493 new AltSvcTransactionChild(cinfo, aCaps);
494 return child.forget();
497 already_AddRefed<PDNSRequestChild> SocketProcessChild::AllocPDNSRequestChild(
498 const nsACString& aHost, const nsACString& aTrrServer, const int32_t& aPort,
499 const uint16_t& aType, const OriginAttributes& aOriginAttributes,
500 const nsIDNSService::DNSFlags& aFlags) {
501 RefPtr<DNSRequestHandler> handler = new DNSRequestHandler();
502 RefPtr<DNSRequestChild> actor = new DNSRequestChild(handler);
503 return actor.forget();
506 mozilla::ipc::IPCResult SocketProcessChild::RecvPDNSRequestConstructor(
507 PDNSRequestChild* aActor, const nsACString& aHost,
508 const nsACString& aTrrServer, const int32_t& aPort, const uint16_t& aType,
509 const OriginAttributes& aOriginAttributes,
510 const nsIDNSService::DNSFlags& aFlags) {
511 RefPtr<DNSRequestChild> actor = static_cast<DNSRequestChild*>(aActor);
512 RefPtr<DNSRequestHandler> handler =
513 actor->GetDNSRequest()->AsDNSRequestHandler();
514 handler->DoAsyncResolve(aHost, aTrrServer, aPort, aType, aOriginAttributes,
515 aFlags);
516 return IPC_OK();
519 void SocketProcessChild::AddDataBridgeToMap(
520 uint64_t aChannelId, BackgroundDataBridgeParent* aActor) {
521 MutexAutoLock lock(mMutex);
522 mBackgroundDataBridgeMap.InsertOrUpdate(aChannelId, RefPtr{aActor});
525 void SocketProcessChild::RemoveDataBridgeFromMap(uint64_t aChannelId) {
526 MutexAutoLock lock(mMutex);
527 mBackgroundDataBridgeMap.Remove(aChannelId);
530 Maybe<RefPtr<BackgroundDataBridgeParent>>
531 SocketProcessChild::GetAndRemoveDataBridge(uint64_t aChannelId) {
532 MutexAutoLock lock(mMutex);
533 return mBackgroundDataBridgeMap.Extract(aChannelId);
536 mozilla::ipc::IPCResult SocketProcessChild::RecvClearSessionCache(
537 ClearSessionCacheResolver&& aResolve) {
538 nsNSSComponent::DoClearSSLExternalAndInternalSessionCache();
539 aResolve(void_t{});
540 return IPC_OK();
543 already_AddRefed<PTRRServiceChild> SocketProcessChild::AllocPTRRServiceChild(
544 const bool& aCaptiveIsPassed, const bool& aParentalControlEnabled,
545 const nsTArray<nsCString>& aDNSSuffixList) {
546 RefPtr<TRRServiceChild> actor = new TRRServiceChild();
547 return actor.forget();
550 mozilla::ipc::IPCResult SocketProcessChild::RecvPTRRServiceConstructor(
551 PTRRServiceChild* aActor, const bool& aCaptiveIsPassed,
552 const bool& aParentalControlEnabled, nsTArray<nsCString>&& aDNSSuffixList) {
553 static_cast<TRRServiceChild*>(aActor)->Init(
554 aCaptiveIsPassed, aParentalControlEnabled, std::move(aDNSSuffixList));
555 return IPC_OK();
558 already_AddRefed<PNativeDNSResolverOverrideChild>
559 SocketProcessChild::AllocPNativeDNSResolverOverrideChild() {
560 RefPtr<NativeDNSResolverOverrideChild> actor =
561 new NativeDNSResolverOverrideChild();
562 return actor.forget();
565 mozilla::ipc::IPCResult
566 SocketProcessChild::RecvPNativeDNSResolverOverrideConstructor(
567 PNativeDNSResolverOverrideChild* aActor) {
568 return IPC_OK();
571 mozilla::ipc::IPCResult SocketProcessChild::RecvNotifyObserver(
572 const nsACString& aTopic, const nsAString& aData) {
573 if (nsCOMPtr<nsIObserverService> obs =
574 mozilla::services::GetObserverService()) {
575 obs->NotifyObservers(nullptr, PromiseFlatCString(aTopic).get(),
576 PromiseFlatString(aData).get());
578 return IPC_OK();
581 namespace {
583 class DataResolverBase {
584 public:
585 // This type is threadsafe-refcounted, as it's referenced on the socket
586 // thread, but must be destroyed on the main thread.
587 NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(
588 DataResolverBase)
590 DataResolverBase() = default;
592 protected:
593 virtual ~DataResolverBase() = default;
596 template <typename DataType, typename ResolverType>
597 class DataResolver final : public DataResolverBase {
598 public:
599 explicit DataResolver(ResolverType&& aResolve)
600 : mResolve(std::move(aResolve)) {}
602 void OnResolve(DataType&& aData) {
603 MOZ_ASSERT(OnSocketThread());
605 RefPtr<DataResolver<DataType, ResolverType>> self = this;
606 mData = std::move(aData);
607 NS_DispatchToMainThread(NS_NewRunnableFunction(
608 "net::DataResolver::OnResolve",
609 [self{std::move(self)}]() { self->mResolve(std::move(self->mData)); }));
612 private:
613 virtual ~DataResolver() = default;
615 ResolverType mResolve;
616 DataType mData;
619 } // anonymous namespace
621 mozilla::ipc::IPCResult SocketProcessChild::RecvGetSocketData(
622 GetSocketDataResolver&& aResolve) {
623 if (!gSocketTransportService) {
624 aResolve(SocketDataArgs());
625 return IPC_OK();
628 RefPtr<
629 DataResolver<SocketDataArgs, SocketProcessChild::GetSocketDataResolver>>
630 resolver = new DataResolver<SocketDataArgs,
631 SocketProcessChild::GetSocketDataResolver>(
632 std::move(aResolve));
633 gSocketTransportService->Dispatch(
634 NS_NewRunnableFunction(
635 "net::SocketProcessChild::RecvGetSocketData",
636 [resolver{std::move(resolver)}]() {
637 SocketDataArgs args;
638 gSocketTransportService->GetSocketConnections(&args.info());
639 args.totalSent() = gSocketTransportService->GetSentBytes();
640 args.totalRecv() = gSocketTransportService->GetReceivedBytes();
641 resolver->OnResolve(std::move(args));
643 NS_DISPATCH_NORMAL);
644 return IPC_OK();
647 mozilla::ipc::IPCResult SocketProcessChild::RecvGetDNSCacheEntries(
648 GetDNSCacheEntriesResolver&& aResolve) {
649 nsresult rv = NS_OK;
650 nsCOMPtr<nsIDNSService> dns;
651 dns = mozilla::components::DNS::Service(&rv);
652 if (NS_FAILED(rv)) {
653 aResolve(nsTArray<DNSCacheEntries>());
654 return IPC_OK();
657 RefPtr<DataResolver<nsTArray<DNSCacheEntries>,
658 SocketProcessChild::GetDNSCacheEntriesResolver>>
659 resolver =
660 new DataResolver<nsTArray<DNSCacheEntries>,
661 SocketProcessChild::GetDNSCacheEntriesResolver>(
662 std::move(aResolve));
663 gSocketTransportService->Dispatch(
664 NS_NewRunnableFunction(
665 "net::SocketProcessChild::RecvGetDNSCacheEntries",
666 [resolver{std::move(resolver)}, dns{std::move(dns)}]() {
667 nsTArray<DNSCacheEntries> entries;
668 dns->GetDNSCacheEntries(&entries);
669 resolver->OnResolve(std::move(entries));
671 NS_DISPATCH_NORMAL);
672 return IPC_OK();
675 mozilla::ipc::IPCResult SocketProcessChild::RecvGetHttpConnectionData(
676 GetHttpConnectionDataResolver&& aResolve) {
677 if (!gSocketTransportService) {
678 aResolve(nsTArray<HttpRetParams>());
679 return IPC_OK();
682 RefPtr<DataResolver<nsTArray<HttpRetParams>,
683 SocketProcessChild::GetHttpConnectionDataResolver>>
684 resolver =
685 new DataResolver<nsTArray<HttpRetParams>,
686 SocketProcessChild::GetHttpConnectionDataResolver>(
687 std::move(aResolve));
688 gSocketTransportService->Dispatch(
689 NS_NewRunnableFunction(
690 "net::SocketProcessChild::RecvGetHttpConnectionData",
691 [resolver{std::move(resolver)}]() {
692 nsTArray<HttpRetParams> data;
693 HttpInfo::GetHttpConnectionData(&data);
694 resolver->OnResolve(std::move(data));
696 NS_DISPATCH_NORMAL);
697 return IPC_OK();
700 mozilla::ipc::IPCResult SocketProcessChild::RecvInitProxyAutoConfigChild(
701 Endpoint<PProxyAutoConfigChild>&& aEndpoint) {
702 // For parsing PAC.
703 if (!sInitializedJS) {
704 JS::DisableJitBackend();
706 // Set all JS::Prefs.
707 SET_JS_PREFS_FROM_BROWSER_PREFS;
709 const char* jsInitFailureReason = JS_InitWithFailureDiagnostic();
710 if (jsInitFailureReason) {
711 MOZ_CRASH_UNSAFE(jsInitFailureReason);
713 sInitializedJS = true;
715 xpc::SelfHostedShmem::GetSingleton();
718 Unused << ProxyAutoConfigChild::Create(std::move(aEndpoint));
719 return IPC_OK();
722 mozilla::ipc::IPCResult SocketProcessChild::RecvRecheckIPConnectivity() {
723 RefPtr<NetworkConnectivityService> ncs =
724 NetworkConnectivityService::GetSingleton();
725 if (ncs) {
726 ncs->RecheckIPConnectivity();
728 return IPC_OK();
731 mozilla::ipc::IPCResult SocketProcessChild::RecvRecheckDNS() {
732 RefPtr<NetworkConnectivityService> ncs =
733 NetworkConnectivityService::GetSingleton();
734 if (ncs) {
735 ncs->RecheckDNS();
737 return IPC_OK();
740 mozilla::ipc::IPCResult SocketProcessChild::RecvFlushFOGData(
741 FlushFOGDataResolver&& aResolver) {
742 glean::FlushFOGData(std::move(aResolver));
743 return IPC_OK();
746 mozilla::ipc::IPCResult SocketProcessChild::RecvTestTriggerMetrics(
747 TestTriggerMetricsResolver&& aResolve) {
748 mozilla::glean::test_only_ipc::a_counter.Add(
749 nsIXULRuntime::PROCESS_TYPE_SOCKET);
750 aResolve(true);
751 return IPC_OK();
754 #if defined(XP_WIN)
755 mozilla::ipc::IPCResult SocketProcessChild::RecvGetUntrustedModulesData(
756 GetUntrustedModulesDataResolver&& aResolver) {
757 RefPtr<DllServices> dllSvc(DllServices::Get());
758 dllSvc->GetUntrustedModulesData()->Then(
759 GetMainThreadSerialEventTarget(), __func__,
760 [aResolver](Maybe<UntrustedModulesData>&& aData) {
761 aResolver(std::move(aData));
763 [aResolver](nsresult aReason) { aResolver(Nothing()); });
764 return IPC_OK();
767 mozilla::ipc::IPCResult
768 SocketProcessChild::RecvUnblockUntrustedModulesThread() {
769 if (nsCOMPtr<nsIObserverService> obs =
770 mozilla::services::GetObserverService()) {
771 obs->NotifyObservers(nullptr, "unblock-untrusted-modules-thread", nullptr);
773 return IPC_OK();
775 #endif // defined(XP_WIN)
777 bool SocketProcessChild::IsShuttingDown() {
778 MutexAutoLock lock(mMutex);
779 return mShuttingDown;
782 void SocketProcessChild::CloseIPCClientCertsActor() {
783 LOG(("SocketProcessChild::CloseIPCClientCertsActor"));
784 MOZ_ASSERT(NS_IsMainThread());
786 mSocketThread->Dispatch(NS_NewRunnableFunction(
787 "CloseIPCClientCertsActor", [self = RefPtr{this}]() {
788 LOG(("CloseIPCClientCertsActor"));
789 if (self->mIPCClientCertsChild) {
790 self->mIPCClientCertsChild->Close();
791 self->mIPCClientCertsChild = nullptr;
793 }));
796 already_AddRefed<psm::IPCClientCertsChild>
797 SocketProcessChild::GetIPCClientCertsActor() {
798 LOG(("SocketProcessChild::GetIPCClientCertsActor"));
799 // Only socket thread can access the mIPCClientCertsChild.
800 if (!OnSocketThread()) {
801 return nullptr;
805 MutexAutoLock lock(mMutex);
806 if (mShuttingDown) {
807 return nullptr;
811 if (mIPCClientCertsChild) {
812 RefPtr<psm::IPCClientCertsChild> actorChild = mIPCClientCertsChild;
813 return actorChild.forget();
816 ipc::Endpoint<psm::PIPCClientCertsParent> parentEndpoint;
817 ipc::Endpoint<psm::PIPCClientCertsChild> childEndpoint;
818 psm::PIPCClientCerts::CreateEndpoints(&parentEndpoint, &childEndpoint);
820 if (NS_FAILED(SocketProcessBackgroundChild::WithActor(
821 "SendInitIPCClientCerts",
822 [endpoint = std::move(parentEndpoint)](
823 SocketProcessBackgroundChild* aActor) mutable {
824 Unused << aActor->SendInitIPCClientCerts(std::move(endpoint));
825 }))) {
826 return nullptr;
829 RefPtr<psm::IPCClientCertsChild> actor = new psm::IPCClientCertsChild();
830 if (!childEndpoint.Bind(actor)) {
831 return nullptr;
834 mIPCClientCertsChild = actor;
835 return actor.forget();
838 } // namespace net
839 } // namespace mozilla