forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			361 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			361 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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/RemoteLazyInputStreamParent.h"
 | |
| #include "mozilla/Telemetry.h"
 | |
| #include "mozilla/TelemetryIPC.h"
 | |
| #include "nsIAppStartup.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<nsIEventTarget> 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());
 | |
| 
 | |
|     if (PR_GetEnv("MOZ_CRASHREPORTER_SHUTDOWN")) {
 | |
|       printf_stderr("Shutting down due to socket process crash.\n");
 | |
|       nsCOMPtr<nsIAppStartup> appService =
 | |
|           do_GetService("@mozilla.org/toolkit/app-startup;1");
 | |
|       if (appService) {
 | |
|         bool userAllowedQuit = true;
 | |
|         appService->Quit(nsIAppStartup::eForceQuit, 1, &userAllowedQuit);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (mHost) {
 | |
|     mHost->OnChannelClosed();
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool SocketProcessParent::SendRequestMemoryReport(
 | |
|     const uint32_t& aGeneration, const bool& aAnonymize,
 | |
|     const bool& aMinimizeMemoryUsage,
 | |
|     const Maybe<ipc::FileDescriptor>& aDMDFile) {
 | |
|   mMemoryReportRequest = MakeUnique<dom::MemoryReportRequestHost>(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<HistogramAccumulation>&& aAccumulations) {
 | |
|   TelemetryIPC::AccumulateChildHistograms(Telemetry::ProcessID::Socket,
 | |
|                                           aAccumulations);
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult SocketProcessParent::RecvAccumulateChildKeyedHistograms(
 | |
|     nsTArray<KeyedHistogramAccumulation>&& aAccumulations) {
 | |
|   TelemetryIPC::AccumulateChildKeyedHistograms(Telemetry::ProcessID::Socket,
 | |
|                                                aAccumulations);
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult SocketProcessParent::RecvUpdateChildScalars(
 | |
|     nsTArray<ScalarAction>&& aScalarActions) {
 | |
|   TelemetryIPC::UpdateChildScalars(Telemetry::ProcessID::Socket,
 | |
|                                    aScalarActions);
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult SocketProcessParent::RecvUpdateChildKeyedScalars(
 | |
|     nsTArray<KeyedScalarAction>&& aScalarActions) {
 | |
|   TelemetryIPC::UpdateChildKeyedScalars(Telemetry::ProcessID::Socket,
 | |
|                                         aScalarActions);
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult SocketProcessParent::RecvRecordChildEvents(
 | |
|     nsTArray<mozilla::Telemetry::ChildEventData>&& 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<TabId>& 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<WebrtcTCPSocketParent*>(aActor);
 | |
|   parent->Release();
 | |
| #endif
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| already_AddRefed<PDNSRequestParent> SocketProcessParent::AllocPDNSRequestParent(
 | |
|     const nsACString& aHost, const nsACString& aTrrServer, const int32_t& port,
 | |
|     const uint16_t& aType, const OriginAttributes& aOriginAttributes,
 | |
|     const nsIDNSService::DNSFlags& aFlags) {
 | |
|   RefPtr<DNSRequestHandler> handler = new DNSRequestHandler();
 | |
|   RefPtr<DNSRequestParent> 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<DNSRequestParent> actor = static_cast<DNSRequestParent*>(aActor);
 | |
|   RefPtr<DNSRequestHandler> 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<nsIHttpActivityDistributor> activityDistributor =
 | |
|       components::HttpActivityDistributor::Service();
 | |
|   MOZ_ASSERT(activityDistributor);
 | |
| 
 | |
|   Unused << activityDistributor->ObserveActivityWithArgs(
 | |
|       aArgs, aActivityType, aActivitySubtype, aTimestamp, aExtraSizeData,
 | |
|       aExtraStringData);
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult SocketProcessParent::RecvInitBackground(
 | |
|     Endpoint<PBackgroundStarterParent>&& aEndpoint) {
 | |
|   LOG(("SocketProcessParent::RecvInitBackground\n"));
 | |
|   if (!ipc::BackgroundParent::AllocStarter(nullptr, std::move(aEndpoint))) {
 | |
|     return IPC_FAIL(this, "BackgroundParent::Alloc failed");
 | |
|   }
 | |
| 
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| already_AddRefed<PAltServiceParent>
 | |
| SocketProcessParent::AllocPAltServiceParent() {
 | |
|   RefPtr<AltServiceParent> actor = new AltServiceParent();
 | |
|   return actor.forget();
 | |
| }
 | |
| 
 | |
| already_AddRefed<PProxyConfigLookupParent>
 | |
| SocketProcessParent::AllocPProxyConfigLookupParent(
 | |
|     nsIURI* aURI, const uint32_t& aProxyResolveFlags) {
 | |
|   RefPtr<ProxyConfigLookupParent> actor =
 | |
|       new ProxyConfigLookupParent(aURI, aProxyResolveFlags);
 | |
|   return actor.forget();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult SocketProcessParent::RecvPProxyConfigLookupConstructor(
 | |
|     PProxyConfigLookupParent* aActor, nsIURI* aURI,
 | |
|     const uint32_t& aProxyResolveFlags) {
 | |
|   static_cast<ProxyConfigLookupParent*>(aActor)->DoProxyLookup();
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult SocketProcessParent::RecvCachePushCheck(
 | |
|     nsIURI* aPushedURL, OriginAttributes&& aOriginAttributes,
 | |
|     nsCString&& aRequestString, CachePushCheckResolver&& aResolver) {
 | |
|   RefPtr<CachePushChecker> 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<SocketProcessParent>&& aParent)
 | |
|       : Runnable("net::DeferredDeleteSocketProcessParent"),
 | |
|         mParent(std::move(aParent)) {}
 | |
| 
 | |
|   NS_IMETHODIMP Run() override { return NS_OK; }
 | |
| 
 | |
|  private:
 | |
|   RefPtr<SocketProcessParent> mParent;
 | |
| };
 | |
| 
 | |
| /* static */
 | |
| void SocketProcessParent::Destroy(RefPtr<SocketProcessParent>&& aParent) {
 | |
|   NS_DispatchToMainThread(
 | |
|       new DeferredDeleteSocketProcessParent(std::move(aParent)));
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult SocketProcessParent::RecvExcludeHttp2OrHttp3(
 | |
|     const HttpConnectionInfoCloneArgs& aArgs) {
 | |
|   RefPtr<nsHttpConnectionInfo> 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<nsIConsoleService> 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<DllServices> 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
 | 
