Bug 1475641 - Move PAProxyAutoConfig to socket process, r=necko-reviewers,dragana

Differential Revision: https://phabricator.services.mozilla.com/D125855
This commit is contained in:
Kershaw Chang 2021-10-11 19:17:58 +00:00
Родитель 6f1e16637d
Коммит 2071bafa77
16 изменённых файлов: 579 добавлений и 27 удалений

Просмотреть файл

@ -28,7 +28,12 @@
#include "nsITimer.h"
#include "mozilla/Atomics.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/net/DNS.h"
#include "mozilla/net/SocketProcessChild.h"
#include "mozilla/net/SocketProcessParent.h"
#include "mozilla/net/ProxyAutoConfigChild.h"
#include "mozilla/net/ProxyAutoConfigParent.h"
#include "mozilla/Utf8.h" // mozilla::Utf8Unit
#include "nsServiceManagerUtils.h"
#include "nsNetCID.h"
@ -366,6 +371,21 @@ class PACResolver final : public nsIDNSListener,
NS_IMPL_ISUPPORTS(PACResolver, nsIDNSListener, nsITimerCallback, nsINamed)
static void PACLogToConsole(nsString& aMessage) {
if (XRE_IsSocketProcess()) {
auto task = [message(aMessage)]() {
SocketProcessChild* child = SocketProcessChild::GetSingleton();
if (child) {
Unused << child->SendOnConsoleMessage(message);
}
};
if (NS_IsMainThread()) {
task();
} else {
NS_DispatchToMainThread(NS_NewRunnableFunction("PACLogToConsole", task));
}
return;
}
nsCOMPtr<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (!consoleService) return;
@ -468,16 +488,19 @@ bool ProxyAutoConfig::ResolveAddress(const nsCString& aHostName,
}
}
mWaitingForDNSResolve = true;
// Spin the event loop of the pac thread until lookup is complete.
// nsPACman is responsible for keeping a queue and only allowing
// one PAC execution at a time even when it is called re-entrantly.
SpinEventLoopUntil("ProxyAutoConfig::ResolveAddress"_ns, [&, helper, this]() {
if (!helper->mRequest) {
mWaitingForDNSResolve = false;
return true;
}
if (this->mShutdown) {
NS_WARNING("mShutdown set with PAC request not cancelled");
MOZ_ASSERT(NS_FAILED(helper->mStatus));
mWaitingForDNSResolve = false;
return true;
}
return false;
@ -693,10 +716,11 @@ void ProxyAutoConfig::SetThreadLocalIndex(uint32_t index) {
RunningIndex() = index;
}
nsresult ProxyAutoConfig::Init(const nsCString& aPACURI,
const nsCString& aPACScriptData,
bool aIncludePath, uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) {
nsresult ProxyAutoConfig::ConfigurePAC(const nsCString& aPACURI,
const nsCString& aPACScriptData,
bool aIncludePath,
uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) {
mShutdown = false; // Shutdown needs to be called prior to destruction
mPACURI = aPACURI;
@ -820,6 +844,15 @@ nsresult ProxyAutoConfig::SetupJS() {
return NS_OK;
}
void ProxyAutoConfig::GetProxyForURIWithCallback(
const nsCString& aTestURI, const nsCString& aTestHost,
std::function<void(nsresult aStatus, const nsACString& aResult)>&&
aCallback) {
nsAutoCString result;
nsresult status = GetProxyForURI(aTestURI, aTestHost, result);
aCallback(status, result);
}
nsresult ProxyAutoConfig::GetProxyForURI(const nsCString& aTestURI,
const nsCString& aTestHost,
nsACString& result) {
@ -1059,5 +1092,72 @@ bool ProxyAutoConfig::MyIPAddress(const JS::CallArgs& aArgs) {
return true;
}
RemoteProxyAutoConfig::RemoteProxyAutoConfig() = default;
RemoteProxyAutoConfig::~RemoteProxyAutoConfig() = default;
nsresult RemoteProxyAutoConfig::Init(nsIThread* aPACThread) {
MOZ_ASSERT(NS_IsMainThread());
SocketProcessParent* socketProcessParent =
SocketProcessParent::GetSingleton();
if (!socketProcessParent) {
return NS_ERROR_NOT_AVAILABLE;
}
ipc::Endpoint<PProxyAutoConfigParent> parent;
ipc::Endpoint<PProxyAutoConfigChild> child;
nsresult rv = PProxyAutoConfig::CreateEndpoints(
base::GetCurrentProcId(), socketProcessParent->OtherPid(), &parent,
&child);
if (NS_FAILED(rv)) {
return rv;
}
Unused << socketProcessParent->SendInitProxyAutoConfigChild(std::move(child));
mProxyAutoConfigParent = new ProxyAutoConfigParent();
return aPACThread->Dispatch(
NS_NewRunnableFunction("ProxyAutoConfigParent::ProxyAutoConfigParent",
[proxyAutoConfigParent(mProxyAutoConfigParent),
endpoint{std::move(parent)}]() mutable {
proxyAutoConfigParent->Init(std::move(endpoint));
}));
}
nsresult RemoteProxyAutoConfig::ConfigurePAC(const nsCString& aPACURI,
const nsCString& aPACScriptData,
bool aIncludePath,
uint32_t aExtraHeapSize,
nsIEventTarget*) {
Unused << mProxyAutoConfigParent->SendConfigurePAC(
aPACURI, aPACScriptData, aIncludePath, aExtraHeapSize);
return NS_OK;
}
void RemoteProxyAutoConfig::Shutdown() { mProxyAutoConfigParent->Close(); }
void RemoteProxyAutoConfig::GC() { Unused << mProxyAutoConfigParent->SendGC(); }
void RemoteProxyAutoConfig::GetProxyForURIWithCallback(
const nsCString& aTestURI, const nsCString& aTestHost,
std::function<void(nsresult aStatus, const nsACString& aResult)>&&
aCallback) {
if (!mProxyAutoConfigParent->CanSend()) {
return;
}
mProxyAutoConfigParent->SendGetProxyForURI(
aTestURI, aTestHost,
[aCallback](Tuple<nsresult, nsCString>&& aResult) {
nsresult status;
nsCString result;
Tie(status, result) = aResult;
aCallback(status, result);
},
[aCallback](mozilla::ipc::ResponseRejectReason&& aReason) {
aCallback(NS_ERROR_FAILURE, ""_ns);
});
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -7,6 +7,7 @@
#ifndef ProxyAutoConfig_h__
#define ProxyAutoConfig_h__
#include <functional>
#include "nsString.h"
#include "nsCOMPtr.h"
@ -20,23 +21,42 @@ namespace mozilla {
namespace net {
class JSContextWrapper;
class ProxyAutoConfigParent;
union NetAddr;
class ProxyAutoConfigBase {
public:
virtual ~ProxyAutoConfigBase() = default;
virtual nsresult Init(nsIThread* aPACThread) { return NS_OK; }
virtual nsresult ConfigurePAC(const nsCString& aPACURI,
const nsCString& aPACScriptData,
bool aIncludePath, uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) = 0;
virtual void SetThreadLocalIndex(uint32_t index) {}
virtual void Shutdown() = 0;
virtual void GC() = 0;
virtual void GetProxyForURIWithCallback(
const nsCString& aTestURI, const nsCString& aTestHost,
std::function<void(nsresult aStatus, const nsACString& aResult)>&&
aCallback) = 0;
};
// The ProxyAutoConfig class is meant to be created and run on a
// non main thread. It synchronously resolves PAC files by blocking that
// thread and running nested event loops. GetProxyForURI is not re-entrant.
class ProxyAutoConfig {
class ProxyAutoConfig : public ProxyAutoConfigBase {
public:
ProxyAutoConfig();
~ProxyAutoConfig();
virtual ~ProxyAutoConfig();
nsresult Init(const nsCString& aPACURI, const nsCString& aPACScriptData,
bool aIncludePath, uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget);
void SetThreadLocalIndex(uint32_t index);
void Shutdown();
void GC();
nsresult ConfigurePAC(const nsCString& aPACURI,
const nsCString& aPACScriptData, bool aIncludePath,
uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) override;
void SetThreadLocalIndex(uint32_t index) override;
void Shutdown() override;
void GC() override;
bool MyIPAddress(const JS::CallArgs& aArgs);
bool ResolveAddress(const nsCString& aHostName, NetAddr* aNetAddr,
unsigned int aTimeout);
@ -78,6 +98,13 @@ class ProxyAutoConfig {
nsresult GetProxyForURI(const nsCString& aTestURI, const nsCString& aTestHost,
nsACString& result);
void GetProxyForURIWithCallback(
const nsCString& aTestURI, const nsCString& aTestHost,
std::function<void(nsresult aStatus, const nsACString& aResult)>&&
aCallback) override;
bool WaitingForDNSResolve() const { return mWaitingForDNSResolve; }
private:
// allow 665ms for myipaddress dns queries. That's 95th percentile.
const static unsigned int kTimeout = 665;
@ -95,12 +122,34 @@ class ProxyAutoConfig {
nsCString mConcatenatedPACData;
nsCString mPACURI;
bool mIncludePath{false};
bool mWaitingForDNSResolve{false};
uint32_t mExtraHeapSize{0};
nsCString mRunningHost;
nsCOMPtr<nsITimer> mTimer;
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
};
class RemoteProxyAutoConfig : public ProxyAutoConfigBase {
public:
RemoteProxyAutoConfig();
virtual ~RemoteProxyAutoConfig();
nsresult Init(nsIThread* aPACThread) override;
nsresult ConfigurePAC(const nsCString& aPACURI,
const nsCString& aPACScriptData, bool aIncludePath,
uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) override;
void Shutdown() override;
void GC() override;
void GetProxyForURIWithCallback(
const nsCString& aTestURI, const nsCString& aTestHost,
std::function<void(nsresult aStatus, const nsACString& aResult)>&&
aCallback) override;
private:
RefPtr<ProxyAutoConfigParent> mProxyAutoConfigParent;
};
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -221,6 +221,7 @@ static const char* gCallbackPrefsForSocketProcess[] = {
"network.dns.skipTRR-when-parental-control-enabled",
"network.offline-mirrors-connectivity",
"network.disable-localhost-when-offline",
"network.proxy.parse_pac_on_socket_process",
nullptr,
};

Просмотреть файл

@ -17,10 +17,12 @@
#include "nsIPromptFactory.h"
#include "nsIProtocolProxyService.h"
#include "nsISystemProxySettings.h"
#include "nsIOService.h"
#include "nsNetUtil.h"
#include "nsThreadUtils.h"
#include "mozilla/Result.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/StaticPrefs_network.h"
#include "mozilla/Telemetry.h"
//-----------------------------------------------------------------------------
@ -270,8 +272,9 @@ class ExecutePACThreadAction final : public Runnable {
mSetupPAC = false;
nsCOMPtr<nsIEventTarget> target = mPACMan->GetNeckoTarget();
mPACMan->mPAC.Init(mSetupPACURI, mSetupPACData, mPACMan->mIncludePath,
mExtraHeapSize, target);
mPACMan->mPAC->ConfigurePAC(mSetupPACURI, mSetupPACData,
mPACMan->mIncludePath, mExtraHeapSize,
target);
RefPtr<PACLoadComplete> runnable = new PACLoadComplete(mPACMan);
mPACMan->Dispatch(runnable.forget());
@ -372,12 +375,18 @@ nsPACMan::nsPACMan(nsISerialEventTarget* mainThreadEventTarget)
mWPADOverDHCPEnabled(false),
mProxyConfigType(0) {
MOZ_ASSERT(NS_IsMainThread(), "pacman must be created on main thread");
if (!sThreadLocalSetup) {
sThreadLocalSetup = true;
PR_NewThreadPrivateIndex(&sThreadLocalIndex, nullptr);
}
mPAC.SetThreadLocalIndex(sThreadLocalIndex);
mIncludePath = Preferences::GetBool(kPACIncludePath, false);
if (StaticPrefs::network_proxy_parse_pac_on_socket_process() &&
gIOService->SocketProcessReady()) {
mPAC = MakeUnique<RemoteProxyAutoConfig>();
} else {
mPAC = MakeUnique<ProxyAutoConfig>();
if (!sThreadLocalSetup) {
sThreadLocalSetup = true;
PR_NewThreadPrivateIndex(&sThreadLocalIndex, nullptr);
}
mPAC->SetThreadLocalIndex(sThreadLocalIndex);
}
}
nsPACMan::~nsPACMan() {
@ -438,6 +447,10 @@ nsresult nsPACMan::DispatchToPAC(already_AddRefed<nsIRunnable> aEvent,
// have to worry about threading issues here.
if (!mPACThread) {
MOZ_TRY(NS_NewNamedThread("ProxyResolution", getter_AddRefs(mPACThread)));
nsresult rv = mPAC->Init(mPACThread);
if (NS_FAILED(rv)) {
return rv;
}
}
return mPACThread->Dispatch(
@ -760,7 +773,9 @@ void nsPACMan::CancelPendingQ(nsresult status, bool aShutdown) {
query->Complete(status, ""_ns);
}
if (aShutdown) mPAC.Shutdown();
if (aShutdown) {
mPAC->Shutdown();
}
}
void nsPACMan::ProcessPendingQ() {
@ -770,10 +785,10 @@ void nsPACMan::ProcessPendingQ() {
}
if (mShutdown) {
mPAC.Shutdown();
mPAC->Shutdown();
} else {
// do GC while the thread has nothing pending
mPAC.GC();
mPAC->GC();
}
}
@ -831,10 +846,13 @@ bool nsPACMan::ProcessPending() {
// the systemproxysettings didn't complete the resolution. try via PAC
if (!completed) {
nsresult status =
mPAC.GetProxyForURI(query->mSpec, query->mHost, pacString);
LOG(("Use proxy from PAC: %s\n", pacString.get()));
query->Complete(status, pacString);
auto callback = [query(query)](nsresult aStatus,
const nsACString& aResult) {
LOG(("Use proxy from PAC: %s\n", PromiseFlatCString(aResult).get()));
query->Complete(aStatus, aResult);
};
mPAC->GetProxyForURIWithCallback(query->mSpec, query->mHost,
std::move(callback));
}
mInProgress = false;

Просмотреть файл

@ -260,7 +260,7 @@ class nsPACMan final : public nsIStreamLoaderObserver,
nsresult DispatchToPAC(already_AddRefed<nsIRunnable> aEvent,
bool aSync = false);
ProxyAutoConfig mPAC;
UniquePtr<ProxyAutoConfigBase> mPAC;
nsCOMPtr<nsIThread> mPACThread;
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
nsCOMPtr<nsIDHCPClient> mDHCPClient;

Просмотреть файл

@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* 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/. */
namespace mozilla {
namespace net {
sync protocol PProxyAutoConfig
{
child:
async ConfigurePAC(nsCString aPACURI, nsCString aPACScriptData,
bool aIncludePath, uint32_t aExtraHeapSize);
async GetProxyForURI(nsCString aTestURI, nsCString aTestHost)
returns (nsresult aStatus, nsCString aResult);
async GC();
};
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -20,6 +20,7 @@ include protocol PTRRService;
include protocol PProxyConfigLookup;
include protocol PNativeDNSResolverOverride;
include protocol PRemoteLazyInputStream;
include protocol PProxyAutoConfig;
#if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
include protocol PSandboxTesting;
@ -136,6 +137,8 @@ parent:
async ExcludeHttp2OrHttp3(HttpConnectionInfoCloneArgs aArgs);
async OnConsoleMessage(nsString aMessage);
child:
async Init(SocketPorcessInitAttributes aAttributes);
async PreferenceUpdate(Pref pref);
@ -181,6 +184,8 @@ child:
async GetHttpConnectionData()
returns (HttpRetParams[] params);
async InitProxyAutoConfigChild(Endpoint<PProxyAutoConfigChild> endpoint);
both:
async PFileDescriptorSet(FileDescriptor fd);
async PDNSRequest(nsCString hostName, nsCString trrServer, uint16_t type,

Просмотреть файл

@ -0,0 +1,199 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "ProxyAutoConfigChild.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/net/SocketProcessChild.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsThreadUtils.h"
#include "ProxyAutoConfig.h"
namespace mozilla::net {
static bool sThreadLocalSetup = false;
static uint32_t sThreadLocalIndex = 0xdeadbeef;
StaticRefPtr<nsIThread> ProxyAutoConfigChild::sPACThread;
bool ProxyAutoConfigChild::sShutdownObserverRegistered = false;
Atomic<uint32_t> ProxyAutoConfigChild::sLiveActorCount(0);
namespace {
class ShutdownObserver final : public nsIObserver {
public:
ShutdownObserver() = default;
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
private:
~ShutdownObserver() = default;
};
NS_IMPL_ISUPPORTS(ShutdownObserver, nsIObserver)
NS_IMETHODIMP
ShutdownObserver::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
ProxyAutoConfigChild::ShutdownPACThread();
return NS_OK;
}
} // namespace
// static
bool ProxyAutoConfigChild::Create(Endpoint<PProxyAutoConfigChild>&& aEndpoint) {
if (!sPACThread && !CreatePACThread()) {
NS_WARNING("Failed to create pac thread!");
return false;
}
if (!sShutdownObserverRegistered) {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return false;
}
nsCOMPtr<nsIObserver> observer = new ShutdownObserver();
nsresult rv = obs->AddObserver(observer, "xpcom-shutdown-threads", false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
sShutdownObserverRegistered = true;
}
RefPtr<ProxyAutoConfigChild> actor = new ProxyAutoConfigChild();
if (NS_FAILED(sPACThread->Dispatch(
NS_NewRunnableFunction("ProxyAutoConfigChild::ProxyAutoConfigChild",
[actor = std::move(actor),
endpoint = std::move(aEndpoint)]() mutable {
MOZ_ASSERT(endpoint.IsValid());
// Transfer ownership to PAC thread. If
// Bind() fails then we will release this
// reference in Destroy.
ProxyAutoConfigChild* actorTmp;
actor.forget(&actorTmp);
if (!endpoint.Bind(actorTmp)) {
actorTmp->Destroy();
}
})))) {
NS_WARNING("Failed to dispatch runnable!");
return false;
}
return true;
}
// static
bool ProxyAutoConfigChild::CreatePACThread() {
MOZ_ASSERT(NS_IsMainThread());
if (SocketProcessChild::GetSingleton()->IsShuttingDown()) {
NS_WARNING("Trying to create pac thread after shutdown has already begun!");
return false;
}
nsCOMPtr<nsIThread> thread;
if (NS_FAILED(NS_NewNamedThread("ProxyResolution", getter_AddRefs(thread)))) {
NS_WARNING("NS_NewNamedThread failed!");
return false;
}
sPACThread = thread.forget();
return true;
}
// static
void ProxyAutoConfigChild::ShutdownPACThread() {
MOZ_ASSERT(NS_IsMainThread());
if (sPACThread) {
// Wait until all actos are released.
SpinEventLoopUntil("ProxyAutoConfigChild::ShutdownPACThread"_ns,
[&]() { return !sLiveActorCount; });
nsCOMPtr<nsIThread> thread = sPACThread.get();
sPACThread = nullptr;
MOZ_ALWAYS_SUCCEEDS(thread->Shutdown());
}
}
ProxyAutoConfigChild::ProxyAutoConfigChild()
: mPAC(MakeUnique<ProxyAutoConfig>()) {
if (!sThreadLocalSetup) {
sThreadLocalSetup = true;
PR_NewThreadPrivateIndex(&sThreadLocalIndex, nullptr);
}
mPAC->SetThreadLocalIndex(sThreadLocalIndex);
sLiveActorCount++;
}
ProxyAutoConfigChild::~ProxyAutoConfigChild() {
MOZ_ASSERT(NS_IsMainThread());
sLiveActorCount--;
}
mozilla::ipc::IPCResult ProxyAutoConfigChild::RecvConfigurePAC(
const nsCString& aPACURI, const nsCString& aPACScriptData,
const bool& aIncludePath, const uint32_t& aExtraHeapSize) {
mPAC->ConfigurePAC(aPACURI, aPACScriptData, aIncludePath, aExtraHeapSize,
GetMainThreadSerialEventTarget());
return IPC_OK();
}
mozilla::ipc::IPCResult ProxyAutoConfigChild::RecvGetProxyForURI(
const nsCString& aTestURI, const nsCString& aTestHost,
GetProxyForURIResolver&& aResolver) {
// When PAC is waiting for DNS result, we need to wait.
if (mPAC->WaitingForDNSResolve()) {
RefPtr<ProxyAutoConfigChild> self = this;
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
"ProxyAutoConfigChild::RecvGetProxyForURI",
[self, testURI(aTestURI), testHost(aTestHost),
resolver{std::move(aResolver)}]() mutable {
self->RecvGetProxyForURI(testURI, testHost, std::move(resolver));
}));
return IPC_OK();
}
nsCString result;
nsresult rv = mPAC->GetProxyForURI(aTestURI, aTestHost, result);
aResolver(Tuple<const nsresult&, const nsCString&>(rv, result));
return IPC_OK();
}
mozilla::ipc::IPCResult ProxyAutoConfigChild::RecvGC() {
mPAC->GC();
return IPC_OK();
}
void ProxyAutoConfigChild::ActorDestroy(ActorDestroyReason aWhy) {
UniquePtr<ProxyAutoConfig> pac(std::move(mPAC));
pac->Shutdown();
// To avoid racing with the main thread, we need to dispatch
// ProxyAutoConfigChild::Destroy again.
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(NewNonOwningRunnableMethod(
"ProxyAutoConfigChild::Destroy", this, &ProxyAutoConfigChild::Destroy)));
}
void ProxyAutoConfigChild::Destroy() {
// May be called on any thread!
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(NewNonOwningRunnableMethod(
"ProxyAutoConfigChild::MainThreadActorDestroy", this,
&ProxyAutoConfigChild::MainThreadActorDestroy)));
}
void ProxyAutoConfigChild::MainThreadActorDestroy() {
MOZ_ASSERT(NS_IsMainThread());
// This may be the last reference!
Release();
}
} // namespace mozilla::net

Просмотреть файл

@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
#ifndef ProxyAutoConfigChild_h__
#define ProxyAutoConfigChild_h__
#include "mozilla/net/PProxyAutoConfigChild.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
namespace net {
class ProxyAutoConfig;
class ProxyAutoConfigChild final : public PProxyAutoConfigChild {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProxyAutoConfigChild)
static bool Create(Endpoint<PProxyAutoConfigChild>&& aEndpoint);
static bool CreatePACThread();
static void ShutdownPACThread();
ProxyAutoConfigChild();
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvConfigurePAC(const nsCString& aPACURI,
const nsCString& aPACScriptData,
const bool& aIncludePath,
const uint32_t& aExtraHeapSize);
mozilla::ipc::IPCResult RecvGetProxyForURI(
const nsCString& aTestURI, const nsCString& aTestHost,
GetProxyForURIResolver&& aResolver);
mozilla::ipc::IPCResult RecvGC();
void Destroy();
private:
virtual ~ProxyAutoConfigChild();
void MainThreadActorDestroy();
UniquePtr<ProxyAutoConfig> mPAC;
static StaticRefPtr<nsIThread> sPACThread;
static bool sShutdownObserverRegistered;
static Atomic<uint32_t> sLiveActorCount;
};
} // namespace net
} // namespace mozilla
#endif // ProxyAutoConfigChild_h__

Просмотреть файл

@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "ProxyAutoConfigParent.h"
#include "mozilla/ipc/Endpoint.h"
#include "nsIConsoleService.h"
namespace mozilla::net {
ProxyAutoConfigParent::ProxyAutoConfigParent() = default;
ProxyAutoConfigParent::~ProxyAutoConfigParent() = default;
void ProxyAutoConfigParent::Init(Endpoint<PProxyAutoConfigParent>&& aEndpoint) {
DebugOnly<bool> ok = aEndpoint.Bind(this);
MOZ_ASSERT(ok);
}
} // namespace mozilla::net

Просмотреть файл

@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
#ifndef ProxyAutoConfigParent_h__
#define ProxyAutoConfigParent_h__
#include "mozilla/net/PProxyAutoConfigParent.h"
namespace mozilla {
namespace net {
class ProxyAutoConfigParent final : public PProxyAutoConfigParent {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProxyAutoConfigParent)
ProxyAutoConfigParent();
void Init(Endpoint<PProxyAutoConfigParent>&& aEndpoint);
private:
virtual ~ProxyAutoConfigParent();
};
} // namespace net
} // namespace mozilla
#endif // ProxyAutoConfigParent_h__

Просмотреть файл

@ -25,12 +25,14 @@
#include "mozilla/net/DNSRequestChild.h"
#include "mozilla/net/DNSRequestParent.h"
#include "mozilla/net/NativeDNSResolverOverrideChild.h"
#include "mozilla/net/ProxyAutoConfigChild.h"
#include "mozilla/net/TRRServiceChild.h"
#include "mozilla/ipc/PChildToParentStreamChild.h"
#include "mozilla/ipc/PParentToChildStreamChild.h"
#include "mozilla/ipc/ProcessUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/RemoteLazyInputStreamChild.h"
#include "mozilla/StaticPrefs_network.h"
#include "mozilla/Telemetry.h"
#include "nsDebugImpl.h"
#include "nsHttpConnectionInfo.h"
@ -42,6 +44,9 @@
#include "nsSocketTransportService2.h"
#include "nsThreadManager.h"
#include "SocketProcessBridgeParent.h"
#include "jsapi.h"
#include "js/Initialization.h"
#include "XPCSelfHostedShmem.h"
#if defined(XP_WIN)
# include <process.h>
@ -68,6 +73,8 @@ namespace net {
using namespace ipc;
static bool sInitializedJS = false;
SocketProcessChild* sSocketProcessChild;
SocketProcessChild::SocketProcessChild() {
@ -121,6 +128,17 @@ bool SocketProcessChild::Init(base::ProcessId aParentPid,
return false;
}
if (StaticPrefs::network_proxy_parse_pac_on_socket_process()) {
// For parsing PAC.
const char* jsInitFailureReason = JS_InitWithFailureDiagnostic();
if (jsInitFailureReason) {
MOZ_CRASH_UNSAFE(jsInitFailureReason);
}
sInitializedJS = true;
xpc::SelfHostedShmem::GetSingleton();
}
BackgroundChild::Startup();
SetThisProcessName("Socket Process");
#if defined(XP_MACOSX)
@ -181,6 +199,10 @@ void SocketProcessChild::CleanUp() {
mBackgroundDataBridgeMap.Clear();
}
NS_ShutdownXPCOM(nullptr);
if (sInitializedJS) {
JS_ShutDown();
}
}
mozilla::ipc::IPCResult SocketProcessChild::RecvInit(
@ -618,5 +640,11 @@ mozilla::ipc::IPCResult SocketProcessChild::RecvGetHttpConnectionData(
return IPC_OK();
}
mozilla::ipc::IPCResult SocketProcessChild::RecvInitProxyAutoConfigChild(
Endpoint<PProxyAutoConfigChild>&& aEndpoint) {
Unused << ProxyAutoConfigChild::Create(std::move(aEndpoint));
return IPC_OK();
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -19,6 +19,7 @@ class ChildProfilerController;
namespace mozilla {
namespace net {
class ProxyAutoConfigChild;
class SocketProcessBridgeParent;
class BackgroundDataBridgeParent;
@ -141,6 +142,9 @@ class SocketProcessChild final
mozilla::ipc::IPCResult RecvGetHttpConnectionData(
GetHttpConnectionDataResolver&& aResolve);
mozilla::ipc::IPCResult RecvInitProxyAutoConfigChild(
Endpoint<PProxyAutoConfigChild>&& aEndpoint);
protected:
friend class SocketProcessImpl;
~SocketProcessChild();

Просмотреть файл

@ -22,6 +22,7 @@
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryIPC.h"
#include "nsIAppStartup.h"
#include "nsIConsoleService.h"
#include "nsIHttpActivityObserver.h"
#include "nsIObserverService.h"
#include "nsNSSIOLayer.h"
@ -456,5 +457,15 @@ mozilla::ipc::IPCResult SocketProcessParent::RecvExcludeHttp2OrHttp3(
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();
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -123,6 +123,7 @@ class SocketProcessParent final
mozilla::ipc::IPCResult RecvExcludeHttp2OrHttp3(
const HttpConnectionInfoCloneArgs& aArgs);
mozilla::ipc::IPCResult RecvOnConsoleMessage(const nsString& aMessage);
private:
SocketProcessHost* mHost;

Просмотреть файл

@ -19,6 +19,8 @@ EXPORTS.mozilla.net += [
"NeckoTargetHolder.h",
"ParentChannelWrapper.h",
"ParentProcessDocumentChannel.h",
"ProxyAutoConfigChild.h",
"ProxyAutoConfigParent.h",
"ProxyConfigLookup.h",
"ProxyConfigLookupChild.h",
"ProxyConfigLookupParent.h",
@ -54,6 +56,12 @@ UNIFIED_SOURCES += [
"SocketProcessParent.cpp",
]
SOURCES += [
"ProxyAutoConfigChild.cpp",
"ProxyAutoConfigParent.cpp",
]
PREPROCESSED_IPDL_SOURCES += [
"PNecko.ipdl",
"PSocketProcess.ipdl",
@ -65,6 +73,7 @@ IPDL_SOURCES = [
"PDocumentChannel.ipdl",
"PFileChannel.ipdl",
"PInputChannelThrottleQueue.ipdl",
"PProxyAutoConfig.ipdl",
"PProxyConfigLookup.ipdl",
"PSimpleChannel.ipdl",
"PSocketProcessBridge.ipdl",