SocketProcessParent.cpp (12106B)
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/. */ 5 6 #include "SocketProcessParent.h" 7 #include "SocketProcessLogging.h" 8 9 #include "AltServiceParent.h" 10 #include "HttpTransactionParent.h" 11 #include "SocketProcessHost.h" 12 #include "TLSClientAuthCertSelection.h" 13 #include "mozilla/Atomics.h" 14 #include "mozilla/Components.h" 15 #include "mozilla/dom/MemoryReportRequest.h" 16 #include "mozilla/FOGIPC.h" 17 #include "mozilla/GeckoTrace.h" 18 #include "mozilla/net/DNSRequestParent.h" 19 #include "mozilla/net/ProxyConfigLookupParent.h" 20 #include "mozilla/net/SocketProcessBackgroundParent.h" 21 #include "mozilla/RemoteLazyInputStreamParent.h" 22 #include "mozilla/Telemetry.h" 23 #include "mozilla/TelemetryIPC.h" 24 #include "nsIConsoleService.h" 25 #include "nsIHttpActivityObserver.h" 26 #include "nsIObserverService.h" 27 #include "nsNSSCertificate.h" 28 #include "nsNSSComponent.h" 29 #include "nsIOService.h" 30 #include "nsHttpHandler.h" 31 #include "nsHttpConnectionInfo.h" 32 #include "secerr.h" 33 #ifdef MOZ_WEBRTC 34 # include "mozilla/dom/ContentProcessManager.h" 35 # include "mozilla/dom/BrowserParent.h" 36 # include "mozilla/net/WebrtcTCPSocketParent.h" 37 #endif 38 #if defined(MOZ_WIDGET_ANDROID) 39 # include "mozilla/java/GeckoProcessManagerWrappers.h" 40 # include "mozilla/java/GeckoProcessTypeWrappers.h" 41 #endif // defined(MOZ_WIDGET_ANDROID) 42 #if defined(XP_WIN) 43 # include "mozilla/WinDllServices.h" 44 #endif 45 46 namespace mozilla { 47 namespace net { 48 49 static Atomic<SocketProcessParent*> sSocketProcessParent; 50 51 SocketProcessParent::SocketProcessParent(SocketProcessHost* aHost) 52 : mHost(aHost) { 53 MOZ_ASSERT(NS_IsMainThread()); 54 MOZ_ASSERT(mHost); 55 56 MOZ_COUNT_CTOR(SocketProcessParent); 57 sSocketProcessParent = this; 58 } 59 60 SocketProcessParent::~SocketProcessParent() { 61 MOZ_COUNT_DTOR(SocketProcessParent); 62 sSocketProcessParent = nullptr; 63 } 64 65 /* static */ 66 already_AddRefed<SocketProcessParent> SocketProcessParent::GetSingleton() { 67 RefPtr<SocketProcessParent> parent(sSocketProcessParent); 68 return parent.forget(); 69 } 70 71 void SocketProcessParent::ActorDestroy(ActorDestroyReason aWhy) { 72 #if defined(MOZ_WIDGET_ANDROID) 73 nsCOMPtr<nsIEventTarget> launcherThread(ipc::GetIPCLauncher()); 74 MOZ_ASSERT(launcherThread); 75 76 auto procType = java::GeckoProcessType::SOCKET(); 77 auto selector = 78 java::GeckoProcessManager::Selector::New(procType, OtherPid()); 79 80 launcherThread->Dispatch(NS_NewRunnableFunction( 81 "SocketProcessParent::ActorDestroy", 82 [selector = java::GeckoProcessManager::Selector::GlobalRef(selector)]() { 83 java::GeckoProcessManager::ShutdownProcess(selector); 84 })); 85 #endif // defined(MOZ_WIDGET_ANDROID) 86 87 if (aWhy == AbnormalShutdown) { 88 GenerateCrashReport(); 89 MaybeTerminateProcess(); 90 } 91 92 if (mHost) { 93 mHost->OnChannelClosed(); 94 } 95 } 96 97 bool SocketProcessParent::SendRequestMemoryReport( 98 const uint32_t& aGeneration, const bool& aAnonymize, 99 const bool& aMinimizeMemoryUsage, 100 const Maybe<ipc::FileDescriptor>& aDMDFile) { 101 mMemoryReportRequest = MakeUnique<dom::MemoryReportRequestHost>(aGeneration); 102 103 PSocketProcessParent::SendRequestMemoryReport( 104 aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, 105 [&](const uint32_t& aGeneration2) { 106 MOZ_ASSERT(gIOService); 107 if (!gIOService->SocketProcess()) { 108 return; 109 } 110 SocketProcessParent* actor = gIOService->SocketProcess()->GetActor(); 111 if (!actor) { 112 return; 113 } 114 if (actor->mMemoryReportRequest) { 115 actor->mMemoryReportRequest->Finish(aGeneration2); 116 actor->mMemoryReportRequest = nullptr; 117 } 118 }, 119 [&](mozilla::ipc::ResponseRejectReason) { 120 MOZ_ASSERT(gIOService); 121 if (!gIOService->SocketProcess()) { 122 return; 123 } 124 SocketProcessParent* actor = gIOService->SocketProcess()->GetActor(); 125 if (!actor) { 126 return; 127 } 128 actor->mMemoryReportRequest = nullptr; 129 }); 130 131 return true; 132 } 133 134 mozilla::ipc::IPCResult SocketProcessParent::RecvAddMemoryReport( 135 const MemoryReport& aReport) { 136 if (mMemoryReportRequest) { 137 mMemoryReportRequest->RecvReport(aReport); 138 } 139 return IPC_OK(); 140 } 141 142 mozilla::ipc::IPCResult SocketProcessParent::RecvAccumulateChildHistograms( 143 nsTArray<HistogramAccumulation>&& aAccumulations) { 144 TelemetryIPC::AccumulateChildHistograms(Telemetry::ProcessID::Socket, 145 aAccumulations); 146 return IPC_OK(); 147 } 148 149 mozilla::ipc::IPCResult SocketProcessParent::RecvAccumulateChildKeyedHistograms( 150 nsTArray<KeyedHistogramAccumulation>&& aAccumulations) { 151 TelemetryIPC::AccumulateChildKeyedHistograms(Telemetry::ProcessID::Socket, 152 aAccumulations); 153 return IPC_OK(); 154 } 155 156 mozilla::ipc::IPCResult SocketProcessParent::RecvUpdateChildScalars( 157 nsTArray<ScalarAction>&& aScalarActions) { 158 TelemetryIPC::UpdateChildScalars(Telemetry::ProcessID::Socket, 159 aScalarActions); 160 return IPC_OK(); 161 } 162 163 mozilla::ipc::IPCResult SocketProcessParent::RecvUpdateChildKeyedScalars( 164 nsTArray<KeyedScalarAction>&& aScalarActions) { 165 TelemetryIPC::UpdateChildKeyedScalars(Telemetry::ProcessID::Socket, 166 aScalarActions); 167 return IPC_OK(); 168 } 169 170 mozilla::ipc::IPCResult SocketProcessParent::RecvRecordChildEvents( 171 nsTArray<mozilla::Telemetry::ChildEventData>&& aEvents) { 172 TelemetryIPC::RecordChildEvents(Telemetry::ProcessID::Socket, aEvents); 173 return IPC_OK(); 174 } 175 176 mozilla::ipc::IPCResult SocketProcessParent::RecvRecordDiscardedData( 177 const mozilla::Telemetry::DiscardedData& aDiscardedData) { 178 TelemetryIPC::RecordDiscardedData(Telemetry::ProcessID::Socket, 179 aDiscardedData); 180 return IPC_OK(); 181 } 182 183 PWebrtcTCPSocketParent* SocketProcessParent::AllocPWebrtcTCPSocketParent( 184 const Maybe<TabId>& aTabId) { 185 #ifdef MOZ_WEBRTC 186 WebrtcTCPSocketParent* parent = new WebrtcTCPSocketParent(aTabId); 187 parent->AddRef(); 188 return parent; 189 #else 190 return nullptr; 191 #endif 192 } 193 194 bool SocketProcessParent::DeallocPWebrtcTCPSocketParent( 195 PWebrtcTCPSocketParent* aActor) { 196 #ifdef MOZ_WEBRTC 197 WebrtcTCPSocketParent* parent = static_cast<WebrtcTCPSocketParent*>(aActor); 198 parent->Release(); 199 #endif 200 return true; 201 } 202 203 already_AddRefed<PDNSRequestParent> SocketProcessParent::AllocPDNSRequestParent( 204 const nsACString& aHost, const nsACString& aTrrServer, const int32_t& port, 205 const uint16_t& aType, const OriginAttributes& aOriginAttributes, 206 const nsIDNSService::DNSFlags& aFlags) { 207 RefPtr<DNSRequestHandler> handler = new DNSRequestHandler(); 208 RefPtr<DNSRequestParent> actor = new DNSRequestParent(handler); 209 return actor.forget(); 210 } 211 212 mozilla::ipc::IPCResult SocketProcessParent::RecvPDNSRequestConstructor( 213 PDNSRequestParent* aActor, const nsACString& aHost, 214 const nsACString& aTrrServer, const int32_t& port, const uint16_t& aType, 215 const OriginAttributes& aOriginAttributes, 216 const nsIDNSService::DNSFlags& aFlags) { 217 RefPtr<DNSRequestParent> actor = static_cast<DNSRequestParent*>(aActor); 218 RefPtr<DNSRequestHandler> handler = 219 actor->GetDNSRequest()->AsDNSRequestHandler(); 220 handler->DoAsyncResolve(aHost, aTrrServer, port, aType, aOriginAttributes, 221 aFlags); 222 return IPC_OK(); 223 } 224 225 mozilla::ipc::IPCResult SocketProcessParent::RecvObserveHttpActivity( 226 const HttpActivityArgs& aArgs, const uint32_t& aActivityType, 227 const uint32_t& aActivitySubtype, const PRTime& aTimestamp, 228 const uint64_t& aExtraSizeData, const nsACString& aExtraStringData) { 229 nsCOMPtr<nsIHttpActivityDistributor> activityDistributor = 230 components::HttpActivityDistributor::Service(); 231 MOZ_ASSERT(activityDistributor); 232 233 (void)activityDistributor->ObserveActivityWithArgs( 234 aArgs, aActivityType, aActivitySubtype, aTimestamp, aExtraSizeData, 235 aExtraStringData); 236 return IPC_OK(); 237 } 238 239 mozilla::ipc::IPCResult SocketProcessParent::RecvInitSocketBackground( 240 Endpoint<PSocketProcessBackgroundParent>&& aEndpoint) { 241 if (!aEndpoint.IsValid()) { 242 return IPC_FAIL(this, "Invalid endpoint"); 243 } 244 245 nsCOMPtr<nsISerialEventTarget> transportQueue; 246 if (NS_FAILED(NS_CreateBackgroundTaskQueue("SocketBackgroundParentQueue", 247 getter_AddRefs(transportQueue)))) { 248 return IPC_FAIL(this, "NS_CreateBackgroundTaskQueue failed"); 249 } 250 251 transportQueue->Dispatch( 252 NS_NewRunnableFunction("BindSocketBackgroundParent", 253 [endpoint = std::move(aEndpoint)]() mutable { 254 RefPtr<SocketProcessBackgroundParent> parent = 255 new SocketProcessBackgroundParent(); 256 endpoint.Bind(parent); 257 })); 258 return IPC_OK(); 259 } 260 261 already_AddRefed<PAltServiceParent> 262 SocketProcessParent::AllocPAltServiceParent() { 263 RefPtr<AltServiceParent> actor = new AltServiceParent(); 264 return actor.forget(); 265 } 266 267 already_AddRefed<PProxyConfigLookupParent> 268 SocketProcessParent::AllocPProxyConfigLookupParent( 269 nsIURI* aURI, const uint32_t& aProxyResolveFlags) { 270 RefPtr<ProxyConfigLookupParent> actor = 271 new ProxyConfigLookupParent(aURI, aProxyResolveFlags); 272 return actor.forget(); 273 } 274 275 mozilla::ipc::IPCResult SocketProcessParent::RecvPProxyConfigLookupConstructor( 276 PProxyConfigLookupParent* aActor, nsIURI* aURI, 277 const uint32_t& aProxyResolveFlags) { 278 static_cast<ProxyConfigLookupParent*>(aActor)->DoProxyLookup(); 279 return IPC_OK(); 280 } 281 282 // To ensure that IPDL is finished before SocketParent gets deleted. 283 class DeferredDeleteSocketProcessParent : public Runnable { 284 public: 285 explicit DeferredDeleteSocketProcessParent( 286 RefPtr<SocketProcessParent>&& aParent) 287 : Runnable("net::DeferredDeleteSocketProcessParent"), 288 mParent(std::move(aParent)) {} 289 290 NS_IMETHODIMP Run() override { return NS_OK; } 291 292 private: 293 RefPtr<SocketProcessParent> mParent; 294 }; 295 296 /* static */ 297 void SocketProcessParent::Destroy(RefPtr<SocketProcessParent>&& aParent) { 298 NS_DispatchToMainThread( 299 new DeferredDeleteSocketProcessParent(std::move(aParent))); 300 } 301 302 mozilla::ipc::IPCResult SocketProcessParent::RecvExcludeHttp2OrHttp3( 303 const HttpConnectionInfoCloneArgs& aArgs) { 304 RefPtr<nsHttpConnectionInfo> cinfo = 305 nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(aArgs); 306 if (!cinfo) { 307 MOZ_ASSERT(false, "failed to deserizlize http connection info"); 308 return IPC_OK(); 309 } 310 311 if (cinfo->IsHttp3()) { 312 gHttpHandler->ExcludeHttp3(cinfo); 313 } else { 314 gHttpHandler->ExcludeHttp2(cinfo); 315 } 316 return IPC_OK(); 317 } 318 319 mozilla::ipc::IPCResult SocketProcessParent::RecvOnConsoleMessage( 320 const nsString& aMessage) { 321 nsCOMPtr<nsIConsoleService> consoleService = 322 do_GetService(NS_CONSOLESERVICE_CONTRACTID); 323 if (consoleService) { 324 consoleService->LogStringMessage(aMessage.get()); 325 } 326 return IPC_OK(); 327 } 328 329 mozilla::ipc::IPCResult SocketProcessParent::RecvFOGData(ByteBuf&& aBuf) { 330 glean::FOGData(std::move(aBuf)); 331 return IPC_OK(); 332 } 333 334 mozilla::ipc::IPCResult SocketProcessParent::RecvGeckoTraceExport( 335 ByteBuf&& aBuf) { 336 recv_gecko_trace_export(aBuf.mData, aBuf.mLen); 337 return IPC_OK(); 338 } 339 340 #if defined(XP_WIN) 341 mozilla::ipc::IPCResult SocketProcessParent::RecvGetModulesTrust( 342 ModulePaths&& aModPaths, bool aRunAtNormalPriority, 343 GetModulesTrustResolver&& aResolver) { 344 RefPtr<DllServices> dllSvc(DllServices::Get()); 345 dllSvc->GetModulesTrust(std::move(aModPaths), aRunAtNormalPriority) 346 ->Then( 347 GetMainThreadSerialEventTarget(), __func__, 348 [aResolver](ModulesMapResult&& aResult) { 349 aResolver(Some(ModulesMapResult(std::move(aResult)))); 350 }, 351 [aResolver](nsresult aRv) { aResolver(Nothing()); }); 352 return IPC_OK(); 353 } 354 #endif // defined(XP_WIN) 355 356 } // namespace net 357 } // namespace mozilla