/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SocketProcessParent.h" #include "SocketProcessLogging.h" #include "AltServiceParent.h" #include "CachePushChecker.h" #include "HttpTransactionParent.h" #include "SocketProcessHost.h" #include "TLSClientAuthCertSelection.h" #include "mozilla/Components.h" #include "mozilla/dom/MemoryReportRequest.h" #include "mozilla/FOGIPC.h" #include "mozilla/net/DNSRequestParent.h" #include "mozilla/net/ProxyConfigLookupParent.h" #include "mozilla/net/SocketProcessBackgroundParent.h" #include "mozilla/RemoteLazyInputStreamParent.h" #include "mozilla/Telemetry.h" #include "mozilla/TelemetryIPC.h" #include "nsIConsoleService.h" #include "nsIHttpActivityObserver.h" #include "nsIObserverService.h" #include "nsNSSCertificate.h" #include "nsNSSComponent.h" #include "nsIOService.h" #include "nsHttpHandler.h" #include "nsHttpConnectionInfo.h" #include "secerr.h" #ifdef MOZ_WEBRTC # include "mozilla/dom/ContentProcessManager.h" # include "mozilla/dom/BrowserParent.h" # include "mozilla/net/WebrtcTCPSocketParent.h" #endif #if defined(MOZ_WIDGET_ANDROID) # include "mozilla/java/GeckoProcessManagerWrappers.h" # include "mozilla/java/GeckoProcessTypeWrappers.h" #endif // defined(MOZ_WIDGET_ANDROID) #if defined(XP_WIN) # include "mozilla/WinDllServices.h" #endif namespace mozilla { namespace net { static SocketProcessParent* sSocketProcessParent; SocketProcessParent::SocketProcessParent(SocketProcessHost* aHost) : mHost(aHost) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mHost); MOZ_COUNT_CTOR(SocketProcessParent); sSocketProcessParent = this; } SocketProcessParent::~SocketProcessParent() { MOZ_ASSERT(NS_IsMainThread()); MOZ_COUNT_DTOR(SocketProcessParent); sSocketProcessParent = nullptr; } /* static */ SocketProcessParent* SocketProcessParent::GetSingleton() { MOZ_ASSERT(NS_IsMainThread()); return sSocketProcessParent; } void SocketProcessParent::ActorDestroy(ActorDestroyReason aWhy) { #if defined(MOZ_WIDGET_ANDROID) nsCOMPtr launcherThread(ipc::GetIPCLauncher()); MOZ_ASSERT(launcherThread); auto procType = java::GeckoProcessType::SOCKET(); auto selector = java::GeckoProcessManager::Selector::New(procType, OtherPid()); launcherThread->Dispatch(NS_NewRunnableFunction( "SocketProcessParent::ActorDestroy", [selector = java::GeckoProcessManager::Selector::GlobalRef(selector)]() { java::GeckoProcessManager::ShutdownProcess(selector); })); #endif // defined(MOZ_WIDGET_ANDROID) if (aWhy == AbnormalShutdown) { GenerateCrashReport(OtherPid()); MaybeTerminateProcess(); } if (mHost) { mHost->OnChannelClosed(); } } bool SocketProcessParent::SendRequestMemoryReport( const uint32_t& aGeneration, const bool& aAnonymize, const bool& aMinimizeMemoryUsage, const Maybe& aDMDFile) { mMemoryReportRequest = MakeUnique(aGeneration); PSocketProcessParent::SendRequestMemoryReport( aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, [&](const uint32_t& aGeneration2) { MOZ_ASSERT(gIOService); if (!gIOService->SocketProcess()) { return; } SocketProcessParent* actor = gIOService->SocketProcess()->GetActor(); if (!actor) { return; } if (actor->mMemoryReportRequest) { actor->mMemoryReportRequest->Finish(aGeneration2); actor->mMemoryReportRequest = nullptr; } }, [&](mozilla::ipc::ResponseRejectReason) { MOZ_ASSERT(gIOService); if (!gIOService->SocketProcess()) { return; } SocketProcessParent* actor = gIOService->SocketProcess()->GetActor(); if (!actor) { return; } actor->mMemoryReportRequest = nullptr; }); return true; } mozilla::ipc::IPCResult SocketProcessParent::RecvAddMemoryReport( const MemoryReport& aReport) { if (mMemoryReportRequest) { mMemoryReportRequest->RecvReport(aReport); } return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvAccumulateChildHistograms( nsTArray&& aAccumulations) { TelemetryIPC::AccumulateChildHistograms(Telemetry::ProcessID::Socket, aAccumulations); return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvAccumulateChildKeyedHistograms( nsTArray&& aAccumulations) { TelemetryIPC::AccumulateChildKeyedHistograms(Telemetry::ProcessID::Socket, aAccumulations); return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvUpdateChildScalars( nsTArray&& aScalarActions) { TelemetryIPC::UpdateChildScalars(Telemetry::ProcessID::Socket, aScalarActions); return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvUpdateChildKeyedScalars( nsTArray&& aScalarActions) { TelemetryIPC::UpdateChildKeyedScalars(Telemetry::ProcessID::Socket, aScalarActions); return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvRecordChildEvents( nsTArray&& aEvents) { TelemetryIPC::RecordChildEvents(Telemetry::ProcessID::Socket, aEvents); return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvRecordDiscardedData( const mozilla::Telemetry::DiscardedData& aDiscardedData) { TelemetryIPC::RecordDiscardedData(Telemetry::ProcessID::Socket, aDiscardedData); return IPC_OK(); } PWebrtcTCPSocketParent* SocketProcessParent::AllocPWebrtcTCPSocketParent( const Maybe& aTabId) { #ifdef MOZ_WEBRTC WebrtcTCPSocketParent* parent = new WebrtcTCPSocketParent(aTabId); parent->AddRef(); return parent; #else return nullptr; #endif } bool SocketProcessParent::DeallocPWebrtcTCPSocketParent( PWebrtcTCPSocketParent* aActor) { #ifdef MOZ_WEBRTC WebrtcTCPSocketParent* parent = static_cast(aActor); parent->Release(); #endif return true; } already_AddRefed SocketProcessParent::AllocPDNSRequestParent( const nsACString& aHost, const nsACString& aTrrServer, const int32_t& port, const uint16_t& aType, const OriginAttributes& aOriginAttributes, const nsIDNSService::DNSFlags& aFlags) { RefPtr handler = new DNSRequestHandler(); RefPtr actor = new DNSRequestParent(handler); return actor.forget(); } mozilla::ipc::IPCResult SocketProcessParent::RecvPDNSRequestConstructor( PDNSRequestParent* aActor, const nsACString& aHost, const nsACString& aTrrServer, const int32_t& port, const uint16_t& aType, const OriginAttributes& aOriginAttributes, const nsIDNSService::DNSFlags& aFlags) { RefPtr actor = static_cast(aActor); RefPtr handler = actor->GetDNSRequest()->AsDNSRequestHandler(); handler->DoAsyncResolve(aHost, aTrrServer, port, aType, aOriginAttributes, aFlags); return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvObserveHttpActivity( const HttpActivityArgs& aArgs, const uint32_t& aActivityType, const uint32_t& aActivitySubtype, const PRTime& aTimestamp, const uint64_t& aExtraSizeData, const nsACString& aExtraStringData) { nsCOMPtr activityDistributor = components::HttpActivityDistributor::Service(); MOZ_ASSERT(activityDistributor); Unused << activityDistributor->ObserveActivityWithArgs( aArgs, aActivityType, aActivitySubtype, aTimestamp, aExtraSizeData, aExtraStringData); return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvInitSocketBackground( Endpoint&& aEndpoint) { if (!aEndpoint.IsValid()) { return IPC_FAIL(this, "Invalid endpoint"); } nsCOMPtr transportQueue; if (NS_FAILED(NS_CreateBackgroundTaskQueue("SocketBackgroundParentQueue", getter_AddRefs(transportQueue)))) { return IPC_FAIL(this, "NS_CreateBackgroundTaskQueue failed"); } transportQueue->Dispatch( NS_NewRunnableFunction("BindSocketBackgroundParent", [endpoint = std::move(aEndpoint)]() mutable { RefPtr parent = new SocketProcessBackgroundParent(); endpoint.Bind(parent); })); return IPC_OK(); } already_AddRefed SocketProcessParent::AllocPAltServiceParent() { RefPtr actor = new AltServiceParent(); return actor.forget(); } already_AddRefed SocketProcessParent::AllocPProxyConfigLookupParent( nsIURI* aURI, const uint32_t& aProxyResolveFlags) { RefPtr actor = new ProxyConfigLookupParent(aURI, aProxyResolveFlags); return actor.forget(); } mozilla::ipc::IPCResult SocketProcessParent::RecvPProxyConfigLookupConstructor( PProxyConfigLookupParent* aActor, nsIURI* aURI, const uint32_t& aProxyResolveFlags) { static_cast(aActor)->DoProxyLookup(); return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvCachePushCheck( nsIURI* aPushedURL, OriginAttributes&& aOriginAttributes, nsCString&& aRequestString, CachePushCheckResolver&& aResolver) { RefPtr checker = new CachePushChecker( aPushedURL, aOriginAttributes, aRequestString, aResolver); if (NS_FAILED(checker->DoCheck())) { aResolver(false); } return IPC_OK(); } // To ensure that IPDL is finished before SocketParent gets deleted. class DeferredDeleteSocketProcessParent : public Runnable { public: explicit DeferredDeleteSocketProcessParent( RefPtr&& aParent) : Runnable("net::DeferredDeleteSocketProcessParent"), mParent(std::move(aParent)) {} NS_IMETHODIMP Run() override { return NS_OK; } private: RefPtr mParent; }; /* static */ void SocketProcessParent::Destroy(RefPtr&& aParent) { NS_DispatchToMainThread( new DeferredDeleteSocketProcessParent(std::move(aParent))); } mozilla::ipc::IPCResult SocketProcessParent::RecvExcludeHttp2OrHttp3( const HttpConnectionInfoCloneArgs& aArgs) { RefPtr cinfo = nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(aArgs); if (!cinfo) { MOZ_ASSERT(false, "failed to deserizlize http connection info"); return IPC_OK(); } if (cinfo->IsHttp3()) { gHttpHandler->ExcludeHttp3(cinfo); } else { gHttpHandler->ExcludeHttp2(cinfo); } return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvOnConsoleMessage( const nsString& aMessage) { nsCOMPtr consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); if (consoleService) { consoleService->LogStringMessage(aMessage.get()); } return IPC_OK(); } mozilla::ipc::IPCResult SocketProcessParent::RecvFOGData(ByteBuf&& aBuf) { glean::FOGData(std::move(aBuf)); return IPC_OK(); } #if defined(XP_WIN) mozilla::ipc::IPCResult SocketProcessParent::RecvGetModulesTrust( ModulePaths&& aModPaths, bool aRunAtNormalPriority, GetModulesTrustResolver&& aResolver) { RefPtr dllSvc(DllServices::Get()); dllSvc->GetModulesTrust(std::move(aModPaths), aRunAtNormalPriority) ->Then( GetMainThreadSerialEventTarget(), __func__, [aResolver](ModulesMapResult&& aResult) { aResolver(Some(ModulesMapResult(std::move(aResult)))); }, [aResolver](nsresult aRv) { aResolver(Nothing()); }); return IPC_OK(); } #endif // defined(XP_WIN) } // namespace net } // namespace mozilla