Backed out 10 changesets (bug 1803810) for xpcshell failures on test_import_global...
[gecko.git] / netwerk / ipc / SocketProcessChild.cpp
blob000ebde2fd30cfa38d87aa4de5312244162a6d2f
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 #endif
65 #include "ChildProfilerController.h"
67 #ifdef MOZ_WEBRTC
68 # include "mozilla/net/WebrtcTCPSocketChild.h"
69 #endif
71 #if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
72 # include "mozilla/SandboxTestingChild.h"
73 #endif
75 namespace mozilla {
76 namespace net {
78 using namespace ipc;
80 static bool sInitializedJS = false;
82 static Atomic<SocketProcessChild*> sSocketProcessChild;
84 SocketProcessChild::SocketProcessChild() {
85 LOG(("CONSTRUCT SocketProcessChild::SocketProcessChild\n"));
86 nsDebugImpl::SetMultiprocessMode("Socket");
88 MOZ_COUNT_CTOR(SocketProcessChild);
89 sSocketProcessChild = this;
92 SocketProcessChild::~SocketProcessChild() {
93 LOG(("DESTRUCT SocketProcessChild::SocketProcessChild\n"));
94 MOZ_COUNT_DTOR(SocketProcessChild);
95 sSocketProcessChild = nullptr;
98 /* static */
99 SocketProcessChild* SocketProcessChild::GetSingleton() {
100 return sSocketProcessChild;
103 #if defined(XP_MACOSX)
104 extern "C" {
105 void CGSShutdownServerConnections();
107 #endif
109 void SocketProcessChild::InitSocketBackground() {
110 Endpoint<PSocketProcessBackgroundParent> parentEndpoint;
111 Endpoint<PSocketProcessBackgroundChild> childEndpoint;
112 if (NS_WARN_IF(NS_FAILED(PSocketProcessBackground::CreateEndpoints(
113 &parentEndpoint, &childEndpoint)))) {
114 return;
117 SocketProcessBackgroundChild::Create(std::move(childEndpoint));
119 Unused << SendInitSocketBackground(std::move(parentEndpoint));
122 namespace {
124 class NetTeardownObserver final : public nsIObserver {
125 public:
126 NetTeardownObserver() = default;
128 NS_DECL_ISUPPORTS
129 NS_DECL_NSIOBSERVER
131 private:
132 ~NetTeardownObserver() = default;
135 NS_IMPL_ISUPPORTS(NetTeardownObserver, nsIObserver)
137 NS_IMETHODIMP
138 NetTeardownObserver::Observe(nsISupports* aSubject, const char* aTopic,
139 const char16_t* aData) {
140 if (SocketProcessChild* child = SocketProcessChild::GetSingleton()) {
141 child->CloseIPCClientCertsActor();
144 return NS_OK;
147 } // namespace
149 bool SocketProcessChild::Init(mozilla::ipc::UntypedEndpoint&& aEndpoint,
150 const char* aParentBuildID) {
151 if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) {
152 return false;
154 if (NS_WARN_IF(!aEndpoint.Bind(this))) {
155 return false;
157 // This must be sent before any IPDL message, which may hit sentinel
158 // errors due to parent and content processes having different
159 // versions.
160 MessageChannel* channel = GetIPCChannel();
161 if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) {
162 // We need to quit this process if the buildID doesn't match the parent's.
163 // This can occur when an update occurred in the background.
164 ProcessChild::QuickExit();
167 // Init crash reporter support.
168 CrashReporterClient::InitSingleton(this);
170 if (NS_FAILED(NS_InitMinimalXPCOM())) {
171 return false;
174 InitSocketBackground();
176 SetThisProcessName("Socket Process");
177 #if defined(XP_MACOSX)
178 // Close all current connections to the WindowServer. This ensures that the
179 // Activity Monitor will not label the socket process as "Not responding"
180 // because it's not running a native event loop. See bug 1384336.
181 CGSShutdownServerConnections();
182 #endif // XP_MACOSX
184 nsresult rv;
185 nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv);
186 if (NS_FAILED(rv)) {
187 return false;
190 nsCOMPtr<nsIProtocolHandler> handler;
191 rv = ios->GetProtocolHandler("http", getter_AddRefs(handler));
192 if (NS_FAILED(rv)) {
193 return false;
196 // Initialize DNS Service here, since it needs to be done in main thread.
197 nsCOMPtr<nsIDNSService> dns =
198 do_GetService("@mozilla.org/network/dns-service;1", &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 = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID);
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 (AbnormalShutdown == aWhy) {
230 NS_WARNING("Shutting down Socket process early due to a crash!");
231 ProcessChild::QuickExit();
234 // Send the last bits of Glean data over to the main process.
235 glean::FlushFOGData(
236 [](ByteBuf&& aBuf) { glean::SendFOGData(std::move(aBuf)); });
238 if (mProfilerController) {
239 mProfilerController->Shutdown();
240 mProfilerController = nullptr;
243 CrashReporterClient::DestroySingleton();
244 XRE_ShutdownChildProcess();
247 void SocketProcessChild::CleanUp() {
248 LOG(("SocketProcessChild::CleanUp\n"));
250 SocketProcessBackgroundChild::Shutdown();
252 for (const auto& parent : mSocketProcessBridgeParentMap.Values()) {
253 if (parent->CanSend()) {
254 parent->Close();
259 MutexAutoLock lock(mMutex);
260 mBackgroundDataBridgeMap.Clear();
263 // Normally, the IPC channel should be already closed at this point, but
264 // sometimes it's not (bug 1788860). When the channel is closed, calling
265 // Close() again is harmless.
266 Close();
268 NS_ShutdownXPCOM(nullptr);
270 if (sInitializedJS) {
271 JS_ShutDown();
275 mozilla::ipc::IPCResult SocketProcessChild::RecvInit(
276 const SocketPorcessInitAttributes& aAttributes) {
277 Unused << RecvSetOffline(aAttributes.mOffline());
278 Unused << RecvSetConnectivity(aAttributes.mConnectivity());
279 if (aAttributes.mInitSandbox()) {
280 Unused << RecvInitLinuxSandbox(aAttributes.mSandboxBroker());
283 #if defined(XP_WIN)
284 RefPtr<DllServices> dllSvc(DllServices::Get());
285 dllSvc->StartUntrustedModulesProcessor(
286 aAttributes.mIsReadyForBackgroundProcessing());
287 #endif // defined(XP_WIN)
289 return IPC_OK();
292 IPCResult SocketProcessChild::RecvPreferenceUpdate(const Pref& aPref) {
293 Preferences::SetPreference(aPref);
294 return IPC_OK();
297 mozilla::ipc::IPCResult SocketProcessChild::RecvRequestMemoryReport(
298 const uint32_t& aGeneration, const bool& aAnonymize,
299 const bool& aMinimizeMemoryUsage,
300 const Maybe<ipc::FileDescriptor>& aDMDFile,
301 const RequestMemoryReportResolver& aResolver) {
302 nsPrintfCString processName("Socket (pid %u)", (unsigned)getpid());
304 mozilla::dom::MemoryReportRequestClient::Start(
305 aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName,
306 [&](const MemoryReport& aReport) {
307 Unused << GetSingleton()->SendAddMemoryReport(aReport);
309 aResolver);
310 return IPC_OK();
313 mozilla::ipc::IPCResult SocketProcessChild::RecvSetOffline(
314 const bool& aOffline) {
315 LOG(("SocketProcessChild::RecvSetOffline aOffline=%d\n", aOffline));
317 nsCOMPtr<nsIIOService> io(do_GetIOService());
318 NS_ASSERTION(io, "IO Service can not be null");
320 io->SetOffline(aOffline);
322 return IPC_OK();
325 mozilla::ipc::IPCResult SocketProcessChild::RecvSetConnectivity(
326 const bool& aConnectivity) {
327 nsCOMPtr<nsIIOService> io(do_GetIOService());
328 nsCOMPtr<nsIIOServiceInternal> ioInternal(do_QueryInterface(io));
329 NS_ASSERTION(ioInternal, "IO Service can not be null");
331 ioInternal->SetConnectivity(aConnectivity);
333 return IPC_OK();
336 mozilla::ipc::IPCResult SocketProcessChild::RecvInitLinuxSandbox(
337 const Maybe<ipc::FileDescriptor>& aBrokerFd) {
338 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
339 int fd = -1;
340 if (aBrokerFd.isSome()) {
341 fd = aBrokerFd.value().ClonePlatformHandle().release();
343 SetSocketProcessSandbox(fd);
344 #endif // XP_LINUX && MOZ_SANDBOX
345 return IPC_OK();
348 mozilla::ipc::IPCResult SocketProcessChild::RecvInitSocketProcessBridgeParent(
349 const ProcessId& aContentProcessId,
350 Endpoint<mozilla::net::PSocketProcessBridgeParent>&& aEndpoint) {
351 MOZ_ASSERT(NS_IsMainThread());
352 MOZ_ASSERT(!mSocketProcessBridgeParentMap.Contains(aContentProcessId));
354 if (NS_WARN_IF(!aEndpoint.IsValid())) {
355 return IPC_FAIL(this, "invalid endpoint");
358 auto bridge = MakeRefPtr<SocketProcessBridgeParent>(aContentProcessId);
359 MOZ_ALWAYS_TRUE(aEndpoint.Bind(bridge));
361 mSocketProcessBridgeParentMap.InsertOrUpdate(aContentProcessId,
362 std::move(bridge));
363 return IPC_OK();
366 mozilla::ipc::IPCResult SocketProcessChild::RecvInitProfiler(
367 Endpoint<PProfilerChild>&& aEndpoint) {
368 mProfilerController =
369 mozilla::ChildProfilerController::Create(std::move(aEndpoint));
370 return IPC_OK();
373 #if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
374 mozilla::ipc::IPCResult SocketProcessChild::RecvInitSandboxTesting(
375 Endpoint<PSandboxTestingChild>&& aEndpoint) {
376 if (!SandboxTestingChild::Initialize(std::move(aEndpoint))) {
377 return IPC_FAIL(
378 this, "InitSandboxTesting failed to initialise the child process.");
380 return IPC_OK();
382 #endif
384 mozilla::ipc::IPCResult SocketProcessChild::RecvSocketProcessTelemetryPing() {
385 const uint32_t kExpectedUintValue = 42;
386 Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_SOCKET_ONLY_UINT,
387 kExpectedUintValue);
388 return IPC_OK();
391 void SocketProcessChild::DestroySocketProcessBridgeParent(ProcessId aId) {
392 MOZ_ASSERT(NS_IsMainThread());
394 mSocketProcessBridgeParentMap.Remove(aId);
397 PWebrtcTCPSocketChild* SocketProcessChild::AllocPWebrtcTCPSocketChild(
398 const Maybe<TabId>& tabId) {
399 // We don't allocate here: instead we always use IPDL constructor that takes
400 // an existing object
401 MOZ_ASSERT_UNREACHABLE(
402 "AllocPWebrtcTCPSocketChild should not be called on"
403 " socket child");
404 return nullptr;
407 bool SocketProcessChild::DeallocPWebrtcTCPSocketChild(
408 PWebrtcTCPSocketChild* aActor) {
409 #ifdef MOZ_WEBRTC
410 WebrtcTCPSocketChild* child = static_cast<WebrtcTCPSocketChild*>(aActor);
411 child->ReleaseIPDLReference();
412 #endif
413 return true;
416 already_AddRefed<PHttpTransactionChild>
417 SocketProcessChild::AllocPHttpTransactionChild() {
418 RefPtr<HttpTransactionChild> actor = new HttpTransactionChild();
419 return actor.forget();
422 already_AddRefed<PHttpConnectionMgrChild>
423 SocketProcessChild::AllocPHttpConnectionMgrChild(
424 const HttpHandlerInitArgs& aArgs) {
425 LOG(("SocketProcessChild::AllocPHttpConnectionMgrChild \n"));
426 MOZ_ASSERT(gHttpHandler);
427 gHttpHandler->SetHttpHandlerInitArgs(aArgs);
429 RefPtr<HttpConnectionMgrChild> actor = new HttpConnectionMgrChild();
430 return actor.forget();
433 mozilla::ipc::IPCResult SocketProcessChild::RecvUpdateDeviceModelId(
434 const nsACString& aModelId) {
435 MOZ_ASSERT(gHttpHandler);
436 gHttpHandler->SetDeviceModelId(aModelId);
437 return IPC_OK();
440 mozilla::ipc::IPCResult
441 SocketProcessChild::RecvOnHttpActivityDistributorActivated(
442 const bool& aIsActivated) {
443 if (nsCOMPtr<nsIHttpActivityObserver> distributor =
444 components::HttpActivityDistributor::Service()) {
445 distributor->SetIsActive(aIsActivated);
447 return IPC_OK();
450 mozilla::ipc::IPCResult
451 SocketProcessChild::RecvOnHttpActivityDistributorObserveProxyResponse(
452 const bool& aIsEnabled) {
453 nsCOMPtr<nsIHttpActivityDistributor> distributor =
454 do_GetService("@mozilla.org/network/http-activity-distributor;1");
455 if (distributor) {
456 Unused << distributor->SetObserveProxyResponse(aIsEnabled);
458 return IPC_OK();
461 mozilla::ipc::IPCResult
462 SocketProcessChild::RecvOnHttpActivityDistributorObserveConnection(
463 const bool& aIsEnabled) {
464 nsCOMPtr<nsIHttpActivityDistributor> distributor =
465 do_GetService("@mozilla.org/network/http-activity-distributor;1");
466 if (distributor) {
467 Unused << distributor->SetObserveConnection(aIsEnabled);
469 return IPC_OK();
472 already_AddRefed<PInputChannelThrottleQueueChild>
473 SocketProcessChild::AllocPInputChannelThrottleQueueChild(
474 const uint32_t& aMeanBytesPerSecond, const uint32_t& aMaxBytesPerSecond) {
475 RefPtr<InputChannelThrottleQueueChild> p =
476 new InputChannelThrottleQueueChild();
477 p->Init(aMeanBytesPerSecond, aMaxBytesPerSecond);
478 return p.forget();
481 already_AddRefed<PAltSvcTransactionChild>
482 SocketProcessChild::AllocPAltSvcTransactionChild(
483 const HttpConnectionInfoCloneArgs& aConnInfo, const uint32_t& aCaps) {
484 RefPtr<nsHttpConnectionInfo> cinfo =
485 nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(aConnInfo);
486 RefPtr<AltSvcTransactionChild> child =
487 new AltSvcTransactionChild(cinfo, aCaps);
488 return child.forget();
491 already_AddRefed<PDNSRequestChild> SocketProcessChild::AllocPDNSRequestChild(
492 const nsACString& aHost, const nsACString& aTrrServer, const int32_t& aPort,
493 const uint16_t& aType, const OriginAttributes& aOriginAttributes,
494 const nsIDNSService::DNSFlags& aFlags) {
495 RefPtr<DNSRequestHandler> handler = new DNSRequestHandler();
496 RefPtr<DNSRequestChild> actor = new DNSRequestChild(handler);
497 return actor.forget();
500 mozilla::ipc::IPCResult SocketProcessChild::RecvPDNSRequestConstructor(
501 PDNSRequestChild* aActor, const nsACString& aHost,
502 const nsACString& aTrrServer, const int32_t& aPort, const uint16_t& aType,
503 const OriginAttributes& aOriginAttributes,
504 const nsIDNSService::DNSFlags& aFlags) {
505 RefPtr<DNSRequestChild> actor = static_cast<DNSRequestChild*>(aActor);
506 RefPtr<DNSRequestHandler> handler =
507 actor->GetDNSRequest()->AsDNSRequestHandler();
508 handler->DoAsyncResolve(aHost, aTrrServer, aPort, aType, aOriginAttributes,
509 aFlags);
510 return IPC_OK();
513 void SocketProcessChild::AddDataBridgeToMap(
514 uint64_t aChannelId, BackgroundDataBridgeParent* aActor) {
515 MutexAutoLock lock(mMutex);
516 mBackgroundDataBridgeMap.InsertOrUpdate(aChannelId, RefPtr{aActor});
519 void SocketProcessChild::RemoveDataBridgeFromMap(uint64_t aChannelId) {
520 MutexAutoLock lock(mMutex);
521 mBackgroundDataBridgeMap.Remove(aChannelId);
524 Maybe<RefPtr<BackgroundDataBridgeParent>>
525 SocketProcessChild::GetAndRemoveDataBridge(uint64_t aChannelId) {
526 MutexAutoLock lock(mMutex);
527 return mBackgroundDataBridgeMap.Extract(aChannelId);
530 mozilla::ipc::IPCResult SocketProcessChild::RecvClearSessionCache(
531 ClearSessionCacheResolver&& aResolve) {
532 nsNSSComponent::DoClearSSLExternalAndInternalSessionCache();
533 aResolve(void_t{});
534 return IPC_OK();
537 already_AddRefed<PTRRServiceChild> SocketProcessChild::AllocPTRRServiceChild(
538 const bool& aCaptiveIsPassed, const bool& aParentalControlEnabled,
539 const nsTArray<nsCString>& aDNSSuffixList) {
540 RefPtr<TRRServiceChild> actor = new TRRServiceChild();
541 return actor.forget();
544 mozilla::ipc::IPCResult SocketProcessChild::RecvPTRRServiceConstructor(
545 PTRRServiceChild* aActor, const bool& aCaptiveIsPassed,
546 const bool& aParentalControlEnabled, nsTArray<nsCString>&& aDNSSuffixList) {
547 static_cast<TRRServiceChild*>(aActor)->Init(
548 aCaptiveIsPassed, aParentalControlEnabled, std::move(aDNSSuffixList));
549 return IPC_OK();
552 already_AddRefed<PNativeDNSResolverOverrideChild>
553 SocketProcessChild::AllocPNativeDNSResolverOverrideChild() {
554 RefPtr<NativeDNSResolverOverrideChild> actor =
555 new NativeDNSResolverOverrideChild();
556 return actor.forget();
559 mozilla::ipc::IPCResult
560 SocketProcessChild::RecvPNativeDNSResolverOverrideConstructor(
561 PNativeDNSResolverOverrideChild* aActor) {
562 return IPC_OK();
565 mozilla::ipc::IPCResult SocketProcessChild::RecvNotifyObserver(
566 const nsACString& aTopic, const nsAString& aData) {
567 if (nsCOMPtr<nsIObserverService> obs =
568 mozilla::services::GetObserverService()) {
569 obs->NotifyObservers(nullptr, PromiseFlatCString(aTopic).get(),
570 PromiseFlatString(aData).get());
572 return IPC_OK();
575 namespace {
577 class DataResolverBase {
578 public:
579 // This type is threadsafe-refcounted, as it's referenced on the socket
580 // thread, but must be destroyed on the main thread.
581 NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(
582 DataResolverBase)
584 DataResolverBase() = default;
586 protected:
587 virtual ~DataResolverBase() = default;
590 template <typename DataType, typename ResolverType>
591 class DataResolver final : public DataResolverBase {
592 public:
593 explicit DataResolver(ResolverType&& aResolve)
594 : mResolve(std::move(aResolve)) {}
596 void OnResolve(DataType&& aData) {
597 MOZ_ASSERT(OnSocketThread());
599 RefPtr<DataResolver<DataType, ResolverType>> self = this;
600 mData = std::move(aData);
601 NS_DispatchToMainThread(NS_NewRunnableFunction(
602 "net::DataResolver::OnResolve",
603 [self{std::move(self)}]() { self->mResolve(std::move(self->mData)); }));
606 private:
607 virtual ~DataResolver() = default;
609 ResolverType mResolve;
610 DataType mData;
613 } // anonymous namespace
615 mozilla::ipc::IPCResult SocketProcessChild::RecvGetSocketData(
616 GetSocketDataResolver&& aResolve) {
617 if (!gSocketTransportService) {
618 aResolve(SocketDataArgs());
619 return IPC_OK();
622 RefPtr<
623 DataResolver<SocketDataArgs, SocketProcessChild::GetSocketDataResolver>>
624 resolver = new DataResolver<SocketDataArgs,
625 SocketProcessChild::GetSocketDataResolver>(
626 std::move(aResolve));
627 gSocketTransportService->Dispatch(
628 NS_NewRunnableFunction(
629 "net::SocketProcessChild::RecvGetSocketData",
630 [resolver{std::move(resolver)}]() {
631 SocketDataArgs args;
632 gSocketTransportService->GetSocketConnections(&args.info());
633 args.totalSent() = gSocketTransportService->GetSentBytes();
634 args.totalRecv() = gSocketTransportService->GetReceivedBytes();
635 resolver->OnResolve(std::move(args));
637 NS_DISPATCH_NORMAL);
638 return IPC_OK();
641 mozilla::ipc::IPCResult SocketProcessChild::RecvGetDNSCacheEntries(
642 GetDNSCacheEntriesResolver&& aResolve) {
643 nsresult rv = NS_OK;
644 nsCOMPtr<nsIDNSService> dns =
645 do_GetService("@mozilla.org/network/dns-service;1", &rv);
646 if (NS_FAILED(rv)) {
647 aResolve(nsTArray<DNSCacheEntries>());
648 return IPC_OK();
651 RefPtr<DataResolver<nsTArray<DNSCacheEntries>,
652 SocketProcessChild::GetDNSCacheEntriesResolver>>
653 resolver =
654 new DataResolver<nsTArray<DNSCacheEntries>,
655 SocketProcessChild::GetDNSCacheEntriesResolver>(
656 std::move(aResolve));
657 gSocketTransportService->Dispatch(
658 NS_NewRunnableFunction(
659 "net::SocketProcessChild::RecvGetDNSCacheEntries",
660 [resolver{std::move(resolver)}, dns{std::move(dns)}]() {
661 nsTArray<DNSCacheEntries> entries;
662 dns->GetDNSCacheEntries(&entries);
663 resolver->OnResolve(std::move(entries));
665 NS_DISPATCH_NORMAL);
666 return IPC_OK();
669 mozilla::ipc::IPCResult SocketProcessChild::RecvGetHttpConnectionData(
670 GetHttpConnectionDataResolver&& aResolve) {
671 if (!gSocketTransportService) {
672 aResolve(nsTArray<HttpRetParams>());
673 return IPC_OK();
676 RefPtr<DataResolver<nsTArray<HttpRetParams>,
677 SocketProcessChild::GetHttpConnectionDataResolver>>
678 resolver =
679 new DataResolver<nsTArray<HttpRetParams>,
680 SocketProcessChild::GetHttpConnectionDataResolver>(
681 std::move(aResolve));
682 gSocketTransportService->Dispatch(
683 NS_NewRunnableFunction(
684 "net::SocketProcessChild::RecvGetHttpConnectionData",
685 [resolver{std::move(resolver)}]() {
686 nsTArray<HttpRetParams> data;
687 HttpInfo::GetHttpConnectionData(&data);
688 resolver->OnResolve(std::move(data));
690 NS_DISPATCH_NORMAL);
691 return IPC_OK();
694 mozilla::ipc::IPCResult SocketProcessChild::RecvInitProxyAutoConfigChild(
695 Endpoint<PProxyAutoConfigChild>&& aEndpoint) {
696 // For parsing PAC.
697 if (!sInitializedJS) {
698 JS::DisableJitBackend();
700 // Set all JS::Prefs.
701 SET_JS_PREFS_FROM_BROWSER_PREFS;
703 const char* jsInitFailureReason = JS_InitWithFailureDiagnostic();
704 if (jsInitFailureReason) {
705 MOZ_CRASH_UNSAFE(jsInitFailureReason);
707 sInitializedJS = true;
709 xpc::SelfHostedShmem::GetSingleton();
712 Unused << ProxyAutoConfigChild::Create(std::move(aEndpoint));
713 return IPC_OK();
716 mozilla::ipc::IPCResult SocketProcessChild::RecvRecheckIPConnectivity() {
717 RefPtr<NetworkConnectivityService> ncs =
718 NetworkConnectivityService::GetSingleton();
719 if (ncs) {
720 ncs->RecheckIPConnectivity();
722 return IPC_OK();
725 mozilla::ipc::IPCResult SocketProcessChild::RecvRecheckDNS() {
726 RefPtr<NetworkConnectivityService> ncs =
727 NetworkConnectivityService::GetSingleton();
728 if (ncs) {
729 ncs->RecheckDNS();
731 return IPC_OK();
734 mozilla::ipc::IPCResult SocketProcessChild::RecvFlushFOGData(
735 FlushFOGDataResolver&& aResolver) {
736 glean::FlushFOGData(std::move(aResolver));
737 return IPC_OK();
740 mozilla::ipc::IPCResult SocketProcessChild::RecvTestTriggerMetrics(
741 TestTriggerMetricsResolver&& aResolve) {
742 mozilla::glean::test_only_ipc::a_counter.Add(
743 nsIXULRuntime::PROCESS_TYPE_SOCKET);
744 aResolve(true);
745 return IPC_OK();
748 #if defined(XP_WIN)
749 mozilla::ipc::IPCResult SocketProcessChild::RecvGetUntrustedModulesData(
750 GetUntrustedModulesDataResolver&& aResolver) {
751 RefPtr<DllServices> dllSvc(DllServices::Get());
752 dllSvc->GetUntrustedModulesData()->Then(
753 GetMainThreadSerialEventTarget(), __func__,
754 [aResolver](Maybe<UntrustedModulesData>&& aData) {
755 aResolver(std::move(aData));
757 [aResolver](nsresult aReason) { aResolver(Nothing()); });
758 return IPC_OK();
761 mozilla::ipc::IPCResult
762 SocketProcessChild::RecvUnblockUntrustedModulesThread() {
763 if (nsCOMPtr<nsIObserverService> obs =
764 mozilla::services::GetObserverService()) {
765 obs->NotifyObservers(nullptr, "unblock-untrusted-modules-thread", nullptr);
767 return IPC_OK();
769 #endif // defined(XP_WIN)
771 bool SocketProcessChild::IsShuttingDown() {
772 MutexAutoLock lock(mMutex);
773 return mShuttingDown;
776 void SocketProcessChild::CloseIPCClientCertsActor() {
777 LOG(("SocketProcessChild::CloseIPCClientCertsActor"));
778 MOZ_ASSERT(NS_IsMainThread());
780 mSocketThread->Dispatch(NS_NewRunnableFunction(
781 "CloseIPCClientCertsActor", [self = RefPtr{this}]() {
782 LOG(("CloseIPCClientCertsActor"));
783 if (self->mIPCClientCertsChild) {
784 self->mIPCClientCertsChild->Close();
785 self->mIPCClientCertsChild = nullptr;
787 }));
790 already_AddRefed<psm::IPCClientCertsChild>
791 SocketProcessChild::GetIPCClientCertsActor() {
792 LOG(("SocketProcessChild::GetIPCClientCertsActor"));
793 // Only socket thread can access the mIPCClientCertsChild.
794 if (!OnSocketThread()) {
795 return nullptr;
799 MutexAutoLock lock(mMutex);
800 if (mShuttingDown) {
801 return nullptr;
805 if (mIPCClientCertsChild) {
806 RefPtr<psm::IPCClientCertsChild> actorChild = mIPCClientCertsChild;
807 return actorChild.forget();
810 ipc::Endpoint<psm::PIPCClientCertsParent> parentEndpoint;
811 ipc::Endpoint<psm::PIPCClientCertsChild> childEndpoint;
812 psm::PIPCClientCerts::CreateEndpoints(&parentEndpoint, &childEndpoint);
814 if (NS_FAILED(SocketProcessBackgroundChild::WithActor(
815 "SendInitIPCClientCerts",
816 [endpoint = std::move(parentEndpoint)](
817 SocketProcessBackgroundChild* aActor) mutable {
818 Unused << aActor->SendInitIPCClientCerts(std::move(endpoint));
819 }))) {
820 return nullptr;
823 RefPtr<psm::IPCClientCertsChild> actor = new psm::IPCClientCertsChild();
824 if (!childEndpoint.Bind(actor)) {
825 return nullptr;
828 mIPCClientCertsChild = actor;
829 return actor.forget();
832 } // namespace net
833 } // namespace mozilla