mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
5dc21d568c
The inclusions were removed with the following very crude script and the resulting breakage was fixed up by hand. The manual fixups did either revert the changes done by the script, replace a generic header with a more specific one or replace a header with a forward declaration. find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2) if [ -n "$interfaces" ]; then if [[ "$interfaces" == *$'\n'* ]]; then regexp="\(" for i in $interfaces; do regexp="$regexp$i\|"; done regexp="${regexp%%\\\|}\)" else regexp="$interfaces" fi interface=$(basename "$path") rg -l "#include.*${interface%%.idl}.h" . | while read path2; do hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" ) if [ $hits -eq 0 ]; then echo "Removing ${interface} from ${path2}" grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp mv -f "$path2".tmp "$path2" fi done fi done Differential Revision: https://phabricator.services.mozilla.com/D55444 --HG-- extra : moz-landing-system : lando
390 lines
13 KiB
C++
390 lines
13 KiB
C++
/* 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 "mozilla/net/ChildDNSService.h"
|
|
#include "nsIDNSListener.h"
|
|
#include "nsThreadUtils.h"
|
|
#include "nsIXPConnect.h"
|
|
#include "nsIProtocolProxyService.h"
|
|
#include "nsNetCID.h"
|
|
#include "mozilla/ClearOnShutdown.h"
|
|
#include "mozilla/StaticPtr.h"
|
|
#include "mozilla/SystemGroup.h"
|
|
#include "mozilla/net/NeckoChild.h"
|
|
#include "mozilla/net/DNSListenerProxy.h"
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
namespace mozilla {
|
|
namespace net {
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ChildDNSService
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static StaticRefPtr<ChildDNSService> gChildDNSService;
|
|
static const char kPrefNameDisablePrefetch[] = "network.dns.disablePrefetch";
|
|
|
|
already_AddRefed<ChildDNSService> ChildDNSService::GetSingleton() {
|
|
MOZ_ASSERT(XRE_IsContentProcess() || XRE_IsSocketProcess());
|
|
|
|
if (!gChildDNSService) {
|
|
gChildDNSService = new ChildDNSService();
|
|
ClearOnShutdown(&gChildDNSService);
|
|
}
|
|
|
|
return do_AddRef(gChildDNSService);
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(ChildDNSService, nsIDNSService, nsPIDNSService, nsIObserver)
|
|
|
|
ChildDNSService::ChildDNSService()
|
|
: mFirstTime(true),
|
|
mDisablePrefetch(false),
|
|
mPendingRequestsLock("DNSPendingRequestsLock") {
|
|
MOZ_ASSERT(XRE_IsContentProcess() || XRE_IsSocketProcess());
|
|
}
|
|
|
|
void ChildDNSService::GetDNSRecordHashKey(
|
|
const nsACString& aHost, uint16_t aType,
|
|
const OriginAttributes& aOriginAttributes, uint32_t aFlags,
|
|
nsIDNSListener* aListener, nsACString& aHashKey) {
|
|
aHashKey.Assign(aHost);
|
|
aHashKey.AppendInt(aType);
|
|
|
|
nsAutoCString originSuffix;
|
|
aOriginAttributes.CreateSuffix(originSuffix);
|
|
aHashKey.Append(originSuffix);
|
|
|
|
aHashKey.AppendInt(aFlags);
|
|
aHashKey.AppendPrintf("%p", aListener);
|
|
}
|
|
|
|
nsresult ChildDNSService::AsyncResolveInternal(
|
|
const nsACString& hostname, uint16_t type, uint32_t flags,
|
|
nsIDNSListener* listener, nsIEventTarget* target_,
|
|
const OriginAttributes& aOriginAttributes, nsICancelable** result) {
|
|
if (XRE_IsContentProcess()) {
|
|
NS_ENSURE_TRUE(gNeckoChild != nullptr, NS_ERROR_FAILURE);
|
|
}
|
|
|
|
if (mDisablePrefetch && (flags & RESOLVE_SPECULATE)) {
|
|
return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
|
|
}
|
|
|
|
// We need original listener for the pending requests hash.
|
|
nsIDNSListener* originalListener = listener;
|
|
|
|
// make sure JS callers get notification on the main thread
|
|
nsCOMPtr<nsIEventTarget> target = target_;
|
|
nsCOMPtr<nsIXPConnectWrappedJS> wrappedListener = do_QueryInterface(listener);
|
|
if (wrappedListener && !target) {
|
|
target = SystemGroup::EventTargetFor(TaskCategory::Network);
|
|
}
|
|
if (target) {
|
|
// Guarantee listener freed on main thread. Not sure we need this in child
|
|
// (or in parent in nsDNSService.cpp) but doesn't hurt.
|
|
listener = new DNSListenerProxy(listener, target);
|
|
}
|
|
|
|
RefPtr<DNSRequestChild> childReq = new DNSRequestChild(
|
|
hostname, type, aOriginAttributes, flags, listener, target);
|
|
|
|
{
|
|
MutexAutoLock lock(mPendingRequestsLock);
|
|
nsCString key;
|
|
GetDNSRecordHashKey(hostname, type, aOriginAttributes, flags,
|
|
originalListener, key);
|
|
auto entry = mPendingRequests.LookupForAdd(key);
|
|
if (entry) {
|
|
entry.Data()->AppendElement(childReq);
|
|
} else {
|
|
entry.OrInsert([&]() {
|
|
auto* hashEntry = new nsTArray<RefPtr<DNSRequestChild>>();
|
|
hashEntry->AppendElement(childReq);
|
|
return hashEntry;
|
|
});
|
|
}
|
|
}
|
|
|
|
childReq->StartRequest();
|
|
|
|
childReq.forget(result);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult ChildDNSService::CancelAsyncResolveInternal(
|
|
const nsACString& aHostname, uint16_t aType, uint32_t aFlags,
|
|
nsIDNSListener* aListener, nsresult aReason,
|
|
const OriginAttributes& aOriginAttributes) {
|
|
if (mDisablePrefetch && (aFlags & RESOLVE_SPECULATE)) {
|
|
return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
|
|
}
|
|
|
|
MutexAutoLock lock(mPendingRequestsLock);
|
|
nsTArray<RefPtr<DNSRequestChild>>* hashEntry;
|
|
nsCString key;
|
|
GetDNSRecordHashKey(aHostname, aType, aOriginAttributes, aFlags, aListener,
|
|
key);
|
|
if (mPendingRequests.Get(key, &hashEntry)) {
|
|
// We cancel just one.
|
|
hashEntry->ElementAt(0)->Cancel(aReason);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ChildDNSService::nsIDNSService
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::AsyncResolve(const nsACString& hostname, uint32_t flags,
|
|
nsIDNSListener* listener, nsIEventTarget* target_,
|
|
JS::HandleValue aOriginAttributes, JSContext* aCx,
|
|
uint8_t aArgc, nsICancelable** result) {
|
|
OriginAttributes attrs;
|
|
|
|
if (aArgc == 1) {
|
|
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
}
|
|
|
|
return AsyncResolveInternal(hostname, nsIDNSService::RESOLVE_TYPE_DEFAULT,
|
|
flags, listener, target_, attrs, result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::AsyncResolveNative(const nsACString& hostname, uint32_t flags,
|
|
nsIDNSListener* listener,
|
|
nsIEventTarget* target_,
|
|
const OriginAttributes& aOriginAttributes,
|
|
nsICancelable** result) {
|
|
return AsyncResolveInternal(hostname, nsIDNSService::RESOLVE_TYPE_DEFAULT,
|
|
flags, listener, target_, aOriginAttributes,
|
|
result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::AsyncResolveByType(const nsACString& hostname, uint16_t type,
|
|
uint32_t flags, nsIDNSListener* listener,
|
|
nsIEventTarget* target_,
|
|
JS::HandleValue aOriginAttributes,
|
|
JSContext* aCx, uint8_t aArgc,
|
|
nsICancelable** result) {
|
|
OriginAttributes attrs;
|
|
|
|
if (aArgc == 1) {
|
|
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
}
|
|
|
|
return AsyncResolveInternal(hostname, type, flags, listener, target_, attrs,
|
|
result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::AsyncResolveByTypeNative(
|
|
const nsACString& hostname, uint16_t type, uint32_t flags,
|
|
nsIDNSListener* listener, nsIEventTarget* target_,
|
|
const OriginAttributes& aOriginAttributes, nsICancelable** result) {
|
|
return AsyncResolveInternal(hostname, type, flags, listener, target_,
|
|
aOriginAttributes, result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::CancelAsyncResolve(const nsACString& aHostname,
|
|
uint32_t aFlags, nsIDNSListener* aListener,
|
|
nsresult aReason,
|
|
JS::HandleValue aOriginAttributes,
|
|
JSContext* aCx, uint8_t aArgc) {
|
|
OriginAttributes attrs;
|
|
|
|
if (aArgc == 1) {
|
|
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
}
|
|
|
|
return CancelAsyncResolveInternal(aHostname,
|
|
nsIDNSService::RESOLVE_TYPE_DEFAULT, aFlags,
|
|
aListener, aReason, attrs);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::CancelAsyncResolveNative(
|
|
const nsACString& aHostname, uint32_t aFlags, nsIDNSListener* aListener,
|
|
nsresult aReason, const OriginAttributes& aOriginAttributes) {
|
|
return CancelAsyncResolveInternal(aHostname,
|
|
nsIDNSService::RESOLVE_TYPE_DEFAULT, aFlags,
|
|
aListener, aReason, aOriginAttributes);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::CancelAsyncResolveByType(const nsACString& aHostname,
|
|
uint16_t aType, uint32_t aFlags,
|
|
nsIDNSListener* aListener,
|
|
nsresult aReason,
|
|
JS::HandleValue aOriginAttributes,
|
|
JSContext* aCx, uint8_t aArgc) {
|
|
OriginAttributes attrs;
|
|
|
|
if (aArgc == 1) {
|
|
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
}
|
|
|
|
return CancelAsyncResolveInternal(aHostname, aType, aFlags, aListener,
|
|
aReason, attrs);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::CancelAsyncResolveByTypeNative(
|
|
const nsACString& aHostname, uint16_t aType, uint32_t aFlags,
|
|
nsIDNSListener* aListener, nsresult aReason,
|
|
const OriginAttributes& aOriginAttributes) {
|
|
return CancelAsyncResolveInternal(aHostname, aType, aFlags, aListener,
|
|
aReason, aOriginAttributes);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::Resolve(const nsACString& hostname, uint32_t flags,
|
|
JS::HandleValue aOriginAttributes, JSContext* aCx,
|
|
uint8_t aArgc, nsIDNSRecord** result) {
|
|
// not planning to ever support this, since sync IPDL is evil.
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::ResolveNative(const nsACString& hostname, uint32_t flags,
|
|
const OriginAttributes& aOriginAttributes,
|
|
nsIDNSRecord** result) {
|
|
// not planning to ever support this, since sync IPDL is evil.
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::GetDNSCacheEntries(
|
|
nsTArray<mozilla::net::DNSCacheEntries>* args) {
|
|
// Only used by networking dashboard, so may not ever need this in child.
|
|
// (and would provide a way to spy on what hosts other apps are connecting to,
|
|
// unless we start keeping per-app DNS caches).
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::ClearCache(bool aTrrToo) { return NS_ERROR_NOT_AVAILABLE; }
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::ReloadParentalControlEnabled() {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::GetMyHostName(nsACString& result) {
|
|
// TODO: get value from parent during PNecko construction?
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
void ChildDNSService::NotifyRequestDone(DNSRequestChild* aDnsRequest) {
|
|
// We need the original flags and listener for the pending requests hash.
|
|
uint32_t originalFlags = aDnsRequest->mFlags & ~RESOLVE_OFFLINE;
|
|
nsCOMPtr<nsIDNSListener> originalListener = aDnsRequest->mListener;
|
|
nsCOMPtr<nsIDNSListenerProxy> wrapper = do_QueryInterface(originalListener);
|
|
if (wrapper) {
|
|
wrapper->GetOriginalListener(getter_AddRefs(originalListener));
|
|
if (NS_WARN_IF(!originalListener)) {
|
|
MOZ_ASSERT(originalListener);
|
|
return;
|
|
}
|
|
}
|
|
|
|
MutexAutoLock lock(mPendingRequestsLock);
|
|
|
|
nsCString key;
|
|
GetDNSRecordHashKey(aDnsRequest->mHost, aDnsRequest->mType,
|
|
aDnsRequest->mOriginAttributes, originalFlags,
|
|
originalListener, key);
|
|
|
|
nsTArray<RefPtr<DNSRequestChild>>* hashEntry;
|
|
|
|
if (mPendingRequests.Get(key, &hashEntry)) {
|
|
auto idx = hashEntry->IndexOf(aDnsRequest);
|
|
if (idx != nsTArray<RefPtr<DNSRequestChild>>::NoIndex) {
|
|
hashEntry->RemoveElementAt(idx);
|
|
if (hashEntry->IsEmpty()) {
|
|
mPendingRequests.Remove(key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ChildDNSService::nsPIDNSService
|
|
//-----------------------------------------------------------------------------
|
|
|
|
nsresult ChildDNSService::Init() {
|
|
// Disable prefetching either by explicit preference or if a manual proxy
|
|
// is configured
|
|
bool disablePrefetch = false;
|
|
int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
|
|
|
|
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
if (prefs) {
|
|
prefs->GetIntPref("network.proxy.type", &proxyType);
|
|
prefs->GetBoolPref(kPrefNameDisablePrefetch, &disablePrefetch);
|
|
}
|
|
|
|
if (mFirstTime) {
|
|
mFirstTime = false;
|
|
if (prefs) {
|
|
prefs->AddObserver(kPrefNameDisablePrefetch, this, false);
|
|
|
|
// Monitor these to see if there is a change in proxy configuration
|
|
// If a manual proxy is in use, disable prefetch implicitly
|
|
prefs->AddObserver("network.proxy.type", this, false);
|
|
}
|
|
}
|
|
|
|
mDisablePrefetch = disablePrefetch ||
|
|
(proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult ChildDNSService::Shutdown() { return NS_OK; }
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::GetPrefetchEnabled(bool* outVal) {
|
|
*outVal = !mDisablePrefetch;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::SetPrefetchEnabled(bool inVal) {
|
|
mDisablePrefetch = !inVal;
|
|
return NS_OK;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ChildDNSService::nsIObserver
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NS_IMETHODIMP
|
|
ChildDNSService::Observe(nsISupports* subject, const char* topic,
|
|
const char16_t* data) {
|
|
// we are only getting called if a preference has changed.
|
|
NS_ASSERTION(strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0,
|
|
"unexpected observe call");
|
|
|
|
// Reread prefs
|
|
Init();
|
|
return NS_OK;
|
|
}
|
|
|
|
} // namespace net
|
|
} // namespace mozilla
|