--- a/netwerk/dns/ChildDNSService.cpp
+++ b/netwerk/dns/ChildDNSService.cpp
@@ -52,52 +52,110 @@ ChildDNSService::ChildDNSService()
ChildDNSService::~ChildDNSService()
{
}
void
ChildDNSService::GetDNSRecordHashKey(const nsACString &aHost,
+ const OriginAttributes &aOriginAttributes,
uint32_t aFlags,
const nsACString &aNetworkInterface,
nsIDNSListener* aListener,
nsACString &aHashKey)
{
aHashKey.Assign(aHost);
+
+ nsAutoCString originSuffix;
+ aOriginAttributes.CreateSuffix(originSuffix);
+ aHashKey.Assign(originSuffix);
+
aHashKey.AppendInt(aFlags);
if (!aNetworkInterface.IsEmpty()) {
aHashKey.Append(aNetworkInterface);
}
aHashKey.AppendPrintf("%p", aListener);
}
//-----------------------------------------------------------------------------
// 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)
{
- return AsyncResolveExtended(hostname, flags, EmptyCString(), listener,
- target_, result);
+ OriginAttributes attrs;
+
+ if (aArgc == 1) {
+ if (!aOriginAttributes.isObject() ||
+ !attrs.Init(aCx, aOriginAttributes)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ return AsyncResolveExtendedNative(hostname, flags, EmptyCString(),
+ listener, target_, attrs,
+ result);
}
NS_IMETHODIMP
-ChildDNSService::AsyncResolveExtended(const nsACString &hostname,
+ChildDNSService::AsyncResolveNative(const nsACString &hostname,
+ uint32_t flags,
+ nsIDNSListener *listener,
+ nsIEventTarget *target_,
+ const OriginAttributes &aOriginAttributes,
+ nsICancelable **result)
+{
+ return AsyncResolveExtendedNative(hostname, flags, EmptyCString(),
+ listener, target_, aOriginAttributes,
+ result);
+}
+
+NS_IMETHODIMP
+ChildDNSService::AsyncResolveExtended(const nsACString &aHostname,
uint32_t flags,
const nsACString &aNetworkInterface,
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 AsyncResolveExtendedNative(aHostname, flags, aNetworkInterface,
+ listener, target_, attrs,
+ result);
+}
+
+NS_IMETHODIMP
+ChildDNSService::AsyncResolveExtendedNative(const nsACString &hostname,
+ uint32_t flags,
+ const nsACString &aNetworkInterface,
+ nsIDNSListener *listener,
+ nsIEventTarget *target_,
+ const OriginAttributes &aOriginAttributes,
+ nsICancelable **result)
+{
NS_ENSURE_TRUE(gNeckoChild != nullptr, NS_ERROR_FAILURE);
if (mDisablePrefetch && (flags & RESOLVE_SPECULATE)) {
return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
}
// We need original flags for the pending requests hash.
uint32_t originalFlags = flags;
@@ -121,24 +179,26 @@ ChildDNSService::AsyncResolveExtended(co
}
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(nsCString(hostname), flags,
+ new DNSRequestChild(nsCString(hostname),
+ aOriginAttributes,
+ flags,
nsCString(aNetworkInterface),
listener, target);
{
MutexAutoLock lock(mPendingRequestsLock);
nsCString key;
- GetDNSRecordHashKey(hostname, originalFlags, aNetworkInterface,
+ GetDNSRecordHashKey(hostname, aOriginAttributes, originalFlags, aNetworkInterface,
originalListener, key);
nsTArray<RefPtr<DNSRequestChild>> *hashEntry;
if (mPendingRequests.Get(key, &hashEntry)) {
hashEntry->AppendElement(childReq);
} else {
hashEntry = new nsTArray<RefPtr<DNSRequestChild>>();
hashEntry->AppendElement(childReq);
mPendingRequests.Put(key, hashEntry);
@@ -150,55 +210,116 @@ ChildDNSService::AsyncResolveExtended(co
childReq.forget(result);
return NS_OK;
}
NS_IMETHODIMP
ChildDNSService::CancelAsyncResolve(const nsACString &aHostname,
uint32_t aFlags,
nsIDNSListener *aListener,
- nsresult aReason)
+ nsresult aReason,
+ JS::HandleValue aOriginAttributes,
+ JSContext *aCx,
+ uint8_t aArgc)
{
- return CancelAsyncResolveExtended(aHostname, aFlags, EmptyCString(),
- aListener, aReason);
+ OriginAttributes attrs;
+
+ if (aArgc == 1) {
+ if (!aOriginAttributes.isObject() ||
+ !attrs.Init(aCx, aOriginAttributes)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ return CancelAsyncResolveExtendedNative(aHostname, aFlags, EmptyCString(),
+ aListener, aReason, attrs);
+}
+
+NS_IMETHODIMP
+ChildDNSService::CancelAsyncResolveNative(const nsACString &aHostname,
+ uint32_t aFlags,
+ nsIDNSListener *aListener,
+ nsresult aReason,
+ const OriginAttributes &aOriginAttributes)
+{
+ return CancelAsyncResolveExtendedNative(aHostname, aFlags, EmptyCString(),
+ aListener, aReason, aOriginAttributes);
}
NS_IMETHODIMP
ChildDNSService::CancelAsyncResolveExtended(const nsACString &aHostname,
uint32_t aFlags,
const nsACString &aNetworkInterface,
nsIDNSListener *aListener,
- nsresult aReason)
+ 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 CancelAsyncResolveExtendedNative(aHostname, aFlags, aNetworkInterface,
+ aListener, aReason, attrs);
+}
+
+NS_IMETHODIMP
+ChildDNSService::CancelAsyncResolveExtendedNative(const nsACString &aHostname,
+ uint32_t aFlags,
+ const nsACString &aNetworkInterface,
+ 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, aFlags, aNetworkInterface, aListener, key);
+ GetDNSRecordHashKey(aHostname, aOriginAttributes, aFlags,
+ aNetworkInterface, aListener, key);
if (mPendingRequests.Get(key, &hashEntry)) {
// We cancel just one.
hashEntry->ElementAt(0)->Cancel(aReason);
}
return NS_OK;
}
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;
}
@@ -222,17 +343,17 @@ ChildDNSService::NotifyRequestDone(DNSRe
MOZ_ASSERT(originalListener);
return;
}
}
MutexAutoLock lock(mPendingRequestsLock);
nsCString key;
- GetDNSRecordHashKey(aDnsRequest->mHost, originalFlags,
+ GetDNSRecordHashKey(aDnsRequest->mHost, aDnsRequest->mOriginAttributes, originalFlags,
aDnsRequest->mNetworkInterface, originalListener, key);
nsTArray<RefPtr<DNSRequestChild>> *hashEntry;
if (mPendingRequests.Get(key, &hashEntry)) {
int idx;
if ((idx = hashEntry->IndexOf(aDnsRequest))) {
hashEntry->RemoveElementAt(idx);
--- a/netwerk/dns/ChildDNSService.h
+++ b/netwerk/dns/ChildDNSService.h
@@ -36,16 +36,17 @@ public:
void NotifyRequestDone(DNSRequestChild *aDnsRequest);
bool GetOffline() const;
private:
virtual ~ChildDNSService();
void MOZ_ALWAYS_INLINE GetDNSRecordHashKey(const nsACString &aHost,
+ const OriginAttributes &aOriginAttributes,
uint32_t aFlags,
const nsACString &aNetworkInterface,
nsIDNSListener* aListener,
nsACString &aHashKey);
bool mFirstTime;
bool mDisablePrefetch;
--- a/netwerk/dns/DNSRequestChild.cpp
+++ b/netwerk/dns/DNSRequestChild.cpp
@@ -166,40 +166,44 @@ public:
: mDnsRequest(aDnsReq)
, mReasonForCancel(aReason)
{}
NS_IMETHOD Run() override
{
if (mDnsRequest->mIPCOpen) {
// Send request to Parent process.
- mDnsRequest->SendCancelDNSRequest(mDnsRequest->mHost, mDnsRequest->mFlags,
+ mDnsRequest->SendCancelDNSRequest(mDnsRequest->mHost,
+ mDnsRequest->mOriginAttributes,
+ mDnsRequest->mFlags,
mDnsRequest->mNetworkInterface,
mReasonForCancel);
}
return NS_OK;
}
private:
RefPtr<DNSRequestChild> mDnsRequest;
nsresult mReasonForCancel;
};
//-----------------------------------------------------------------------------
// DNSRequestChild
//-----------------------------------------------------------------------------
DNSRequestChild::DNSRequestChild(const nsCString& aHost,
+ const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags,
const nsCString& aNetworkInterface,
nsIDNSListener *aListener,
nsIEventTarget *target)
: mListener(aListener)
, mTarget(target)
, mResultStatus(NS_OK)
, mHost(aHost)
+ , mOriginAttributes(aOriginAttributes)
, mFlags(aFlags)
, mNetworkInterface(aNetworkInterface)
, mIPCOpen(false)
{
}
void
DNSRequestChild::StartRequest()
@@ -207,18 +211,18 @@ DNSRequestChild::StartRequest()
// we can only do IPDL on the main thread
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(
NewRunnableMethod(this, &DNSRequestChild::StartRequest));
return;
}
// Send request to Parent process.
- gNeckoChild->SendPDNSRequestConstructor(this, mHost, mFlags,
- mNetworkInterface);
+ gNeckoChild->SendPDNSRequestConstructor(this, mHost, mOriginAttributes,
+ mFlags, mNetworkInterface);
mIPCOpen = true;
// IPDL holds a reference until IPDL channel gets destroyed
AddIPDLReference();
}
void
DNSRequestChild::CallOnLookupComplete()
--- a/netwerk/dns/DNSRequestChild.h
+++ b/netwerk/dns/DNSRequestChild.h
@@ -19,17 +19,19 @@ namespace net {
class DNSRequestChild final
: public PDNSRequestChild
, public nsICancelable
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICANCELABLE
- DNSRequestChild(const nsCString& aHost, const uint32_t& aFlags,
+ DNSRequestChild(const nsCString& aHost,
+ const OriginAttributes& aOriginAttributes,
+ const uint32_t& aFlags,
const nsCString& aNetworkInterface,
nsIDNSListener *aListener, nsIEventTarget *target);
void AddIPDLReference() {
AddRef();
}
void ReleaseIPDLReference();
@@ -45,16 +47,17 @@ protected:
virtual mozilla::ipc::IPCResult RecvLookupCompleted(const DNSRequestResponse& reply) override;
virtual void ActorDestroy(ActorDestroyReason why) override;
nsCOMPtr<nsIDNSListener> mListener;
nsCOMPtr<nsIEventTarget> mTarget;
nsCOMPtr<nsIDNSRecord> mResultRecord;
nsresult mResultStatus;
nsCString mHost;
+ const OriginAttributes mOriginAttributes;
uint16_t mFlags;
nsCString mNetworkInterface;
bool mIPCOpen;
};
} // namespace net
} // namespace mozilla
--- a/netwerk/dns/DNSRequestParent.cpp
+++ b/netwerk/dns/DNSRequestParent.cpp
@@ -27,46 +27,53 @@ DNSRequestParent::DNSRequestParent()
}
DNSRequestParent::~DNSRequestParent()
{
}
void
-DNSRequestParent::DoAsyncResolve(const nsACString &hostname, uint32_t flags,
+DNSRequestParent::DoAsyncResolve(const nsACString &hostname,
+ const OriginAttributes &originAttributes,
+ uint32_t flags,
const nsACString &networkInterface)
{
nsresult rv;
mFlags = flags;
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
nsCOMPtr<nsICancelable> unused;
- rv = dns->AsyncResolveExtended(hostname, flags, networkInterface, this,
- mainThread, getter_AddRefs(unused));
+ rv = dns->AsyncResolveExtendedNative(hostname, flags,
+ networkInterface, this,
+ mainThread, originAttributes,
+ getter_AddRefs(unused));
}
if (NS_FAILED(rv) && !mIPCClosed) {
mIPCClosed = true;
Unused << SendLookupCompleted(DNSRequestResponse(rv));
}
}
mozilla::ipc::IPCResult
DNSRequestParent::RecvCancelDNSRequest(const nsCString& hostName,
+ const OriginAttributes& originAttributes,
const uint32_t& flags,
const nsCString& networkInterface,
const nsresult& reason)
{
nsresult rv;
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
- rv = dns->CancelAsyncResolveExtended(hostName, flags, networkInterface,
- this, reason);
+ rv = dns->CancelAsyncResolveExtendedNative(hostName, flags,
+ networkInterface,
+ this, reason,
+ originAttributes);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
DNSRequestParent::Recv__delete__()
{
mIPCClosed = true;
--- a/netwerk/dns/DNSRequestParent.h
+++ b/netwerk/dns/DNSRequestParent.h
@@ -19,22 +19,25 @@ class DNSRequestParent
, public nsIDNSListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDNSLISTENER
DNSRequestParent();
- void DoAsyncResolve(const nsACString &hostname, uint32_t flags,
+ void DoAsyncResolve(const nsACString &hostname,
+ const OriginAttributes &originAttributes,
+ uint32_t flags,
const nsACString &networkInterface);
// Pass args here rather than storing them in the parent; they are only
// needed if the request is to be canceled.
mozilla::ipc::IPCResult RecvCancelDNSRequest(const nsCString& hostName,
+ const OriginAttributes& originAttributes,
const uint32_t& flags,
const nsCString& networkInterface,
const nsresult& reason) override;
mozilla::ipc::IPCResult Recv__delete__() override;
protected:
virtual void ActorDestroy(ActorDestroyReason why) override;
private:
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -297,37 +297,40 @@ class nsDNSAsyncRequest final : public n
~nsDNSAsyncRequest() = default;
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICANCELABLE
nsDNSAsyncRequest(nsHostResolver *res,
const nsACString &host,
+ const OriginAttributes &attrs,
nsIDNSListener *listener,
uint16_t flags,
uint16_t af,
const nsACString &netInterface)
: mResolver(res)
, mHost(host)
+ , mOriginAttributes(attrs)
, mListener(listener)
, mFlags(flags)
, mAF(af)
, mNetworkInterface(netInterface) {}
void OnLookupComplete(nsHostResolver *, nsHostRecord *, nsresult) override;
// Returns TRUE if the DNS listener arg is the same as the member listener
// Used in Cancellations to remove DNS requests associated with a
// particular hostname and nsIDNSListener
bool EqualsAsyncListener(nsIDNSListener *aListener) override;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const override;
RefPtr<nsHostResolver> mResolver;
nsCString mHost; // hostname we're resolving
+ const OriginAttributes mOriginAttributes; // The originAttributes for this resolving
nsCOMPtr<nsIDNSListener> mListener;
uint16_t mFlags;
uint16_t mAF;
nsCString mNetworkInterface;
};
void
nsDNSAsyncRequest::OnLookupComplete(nsHostResolver *resolver,
@@ -377,18 +380,18 @@ nsDNSAsyncRequest::SizeOfIncludingThis(M
}
NS_IMPL_ISUPPORTS(nsDNSAsyncRequest, nsICancelable)
NS_IMETHODIMP
nsDNSAsyncRequest::Cancel(nsresult reason)
{
NS_ENSURE_ARG(NS_FAILED(reason));
- mResolver->DetachCallback(mHost.get(), mFlags, mAF, mNetworkInterface.get(),
- this, reason);
+ mResolver->DetachCallback(mHost.get(), mOriginAttributes, mFlags, mAF,
+ mNetworkInterface.get(), this, reason);
return NS_OK;
}
//-----------------------------------------------------------------------------
class nsDNSSyncRequest : public nsResolveHostCallback
{
public:
@@ -714,30 +717,82 @@ nsDNSService::PreprocessHostname(bool
return NS_OK;
}
NS_IMETHODIMP
nsDNSService::AsyncResolve(const nsACString &aHostname,
uint32_t flags,
nsIDNSListener *listener,
nsIEventTarget *target_,
+ JS::HandleValue aOriginAttributes,
+ JSContext *aCx,
+ uint8_t aArgc,
nsICancelable **result)
{
- return AsyncResolveExtended(aHostname, flags, EmptyCString(), listener, target_,
- result);
+ OriginAttributes attrs;
+
+ if (aArgc == 1) {
+ if (!aOriginAttributes.isObject() ||
+ !attrs.Init(aCx, aOriginAttributes)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ return AsyncResolveExtendedNative(aHostname, flags, EmptyCString(),
+ listener, target_, attrs,
+ result);
+}
+
+NS_IMETHODIMP
+nsDNSService::AsyncResolveNative(const nsACString &aHostname,
+ uint32_t flags,
+ nsIDNSListener *listener,
+ nsIEventTarget *target_,
+ const OriginAttributes &aOriginAttributes,
+ nsICancelable **result)
+{
+ return AsyncResolveExtendedNative(aHostname, flags, EmptyCString(),
+ listener, target_, aOriginAttributes,
+ result);
}
NS_IMETHODIMP
nsDNSService::AsyncResolveExtended(const nsACString &aHostname,
uint32_t flags,
const nsACString &aNetworkInterface,
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 AsyncResolveExtendedNative(aHostname, flags, aNetworkInterface,
+ listener, target_, attrs,
+ result);
+}
+
+NS_IMETHODIMP
+nsDNSService::AsyncResolveExtendedNative(const nsACString &aHostname,
+ uint32_t flags,
+ const nsACString &aNetworkInterface,
+ nsIDNSListener *listener,
+ nsIEventTarget *target_,
+ const OriginAttributes &aOriginAttributes,
+ nsICancelable **result)
+{
// grab reference to global host resolver and IDN service. beware
// simultaneous shutdown!!
RefPtr<nsHostResolver> res;
nsCOMPtr<nsIIDNService> idn;
nsCOMPtr<nsIEventTarget> target = target_;
bool localDomain = false;
{
MutexAutoLock lock(mLock);
@@ -778,49 +833,96 @@ nsDNSService::AsyncResolveExtended(const
if (target) {
listener = new DNSListenerProxy(listener, target);
}
uint16_t af = GetAFForLookup(hostname, flags);
auto *req =
- new nsDNSAsyncRequest(res, hostname, listener, flags, af,
+ new nsDNSAsyncRequest(res, hostname, aOriginAttributes, listener, flags, af,
aNetworkInterface);
if (!req)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*result = req);
// addref for resolver; will be released when OnLookupComplete is called.
NS_ADDREF(req);
- rv = res->ResolveHost(req->mHost.get(), flags, af,
+ rv = res->ResolveHost(req->mHost.get(), req->mOriginAttributes, flags, af,
req->mNetworkInterface.get(), req);
if (NS_FAILED(rv)) {
NS_RELEASE(req);
NS_RELEASE(*result);
}
return rv;
}
NS_IMETHODIMP
-nsDNSService::CancelAsyncResolve(const nsACString &aHostname,
- uint32_t aFlags,
- nsIDNSListener *aListener,
- nsresult aReason)
+nsDNSService::CancelAsyncResolve(const nsACString &aHostname,
+ uint32_t aFlags,
+ nsIDNSListener *aListener,
+ nsresult aReason,
+ JS::HandleValue aOriginAttributes,
+ JSContext *aCx,
+ uint8_t aArgc)
{
- return CancelAsyncResolveExtended(aHostname, aFlags, EmptyCString(), aListener,
- aReason);
+ OriginAttributes attrs;
+
+ if (aArgc == 1) {
+ if (!aOriginAttributes.isObject() ||
+ !attrs.Init(aCx, aOriginAttributes)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ return CancelAsyncResolveExtendedNative(aHostname, aFlags, EmptyCString(),
+ aListener, aReason, attrs);
}
NS_IMETHODIMP
-nsDNSService::CancelAsyncResolveExtended(const nsACString &aHostname,
- uint32_t aFlags,
- const nsACString &aNetworkInterface,
- nsIDNSListener *aListener,
- nsresult aReason)
+nsDNSService::CancelAsyncResolveNative(const nsACString &aHostname,
+ uint32_t aFlags,
+ nsIDNSListener *aListener,
+ nsresult aReason,
+ const OriginAttributes &aOriginAttributes)
+{
+ return CancelAsyncResolveExtendedNative(aHostname, aFlags, EmptyCString(),
+ aListener, aReason, aOriginAttributes);
+}
+
+NS_IMETHODIMP
+nsDNSService::CancelAsyncResolveExtended(const nsACString &aHostname,
+ uint32_t aFlags,
+ const nsACString &aNetworkInterface,
+ 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 CancelAsyncResolveExtendedNative(aHostname, aFlags, aNetworkInterface,
+ aListener, aReason, attrs);
+}
+
+NS_IMETHODIMP
+nsDNSService::CancelAsyncResolveExtendedNative(const nsACString &aHostname,
+ uint32_t aFlags,
+ const nsACString &aNetworkInterface,
+ nsIDNSListener *aListener,
+ nsresult aReason,
+ const OriginAttributes &aOriginAttributes)
{
// grab reference to global host resolver and IDN service. beware
// simultaneous shutdown!!
RefPtr<nsHostResolver> res;
nsCOMPtr<nsIIDNService> idn;
bool localDomain = false;
{
MutexAutoLock lock(mLock);
@@ -838,26 +940,47 @@ nsDNSService::CancelAsyncResolveExtended
nsCString hostname;
nsresult rv = PreprocessHostname(localDomain, aHostname, idn, hostname);
if (NS_FAILED(rv)) {
return rv;
}
uint16_t af = GetAFForLookup(hostname, aFlags);
- res->CancelAsyncRequest(hostname.get(), aFlags, af,
+ res->CancelAsyncRequest(hostname.get(), aOriginAttributes, aFlags, af,
nsPromiseFlatCString(aNetworkInterface).get(), aListener,
aReason);
return NS_OK;
}
NS_IMETHODIMP
-nsDNSService::Resolve(const nsACString &aHostname,
- uint32_t flags,
- nsIDNSRecord **result)
+nsDNSService::Resolve(const nsACString &aHostname,
+ uint32_t flags,
+ JS::HandleValue aOriginAttributes,
+ JSContext *aCx,
+ uint8_t aArgc,
+ nsIDNSRecord **result)
+{
+ OriginAttributes attrs;
+
+ if (aArgc == 1) {
+ if (!aOriginAttributes.isObject() ||
+ !attrs.Init(aCx, aOriginAttributes)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ return ResolveNative(aHostname, flags, attrs, result);
+}
+
+NS_IMETHODIMP
+nsDNSService::ResolveNative(const nsACString &aHostname,
+ uint32_t flags,
+ const OriginAttributes &aOriginAttributes,
+ nsIDNSRecord **result)
{
// grab reference to global host resolver and IDN service. beware
// simultaneous shutdown!!
RefPtr<nsHostResolver> res;
nsCOMPtr<nsIIDNService> idn;
bool localDomain = false;
{
MutexAutoLock lock(mLock);
@@ -895,17 +1018,17 @@ nsDNSService::Resolve(const nsACString &
if (!mon)
return NS_ERROR_OUT_OF_MEMORY;
PR_EnterMonitor(mon);
nsDNSSyncRequest syncReq(mon);
uint16_t af = GetAFForLookup(hostname, flags);
- rv = res->ResolveHost(hostname.get(), flags, af, "", &syncReq);
+ rv = res->ResolveHost(hostname.get(), aOriginAttributes, flags, af, "", &syncReq);
if (NS_SUCCEEDED(rv)) {
// wait for result
while (!syncReq.mDone)
PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
if (NS_FAILED(syncReq.mStatus))
rv = syncReq.mStatus;
else {
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -180,29 +180,33 @@ nsHostRecord::nsHostRecord(const nsHostK
{
host = ((char *) this) + sizeof(nsHostRecord);
memcpy((char *) host, key->host, strlen(key->host) + 1);
flags = key->flags;
af = key->af;
netInterface = host + strlen(key->host) + 1;
memcpy((char *) netInterface, key->netInterface,
strlen(key->netInterface) + 1);
+ originSuffix = netInterface + strlen(key->netInterface) + 1;
+ memcpy((char *) originSuffix, key->originSuffix,
+ strlen(key->originSuffix) + 1);
PR_INIT_CLIST(this);
PR_INIT_CLIST(&callbacks);
}
nsresult
nsHostRecord::Create(const nsHostKey *key, nsHostRecord **result)
{
size_t hostLen = strlen(key->host) + 1;
size_t netInterfaceLen = strlen(key->netInterface) + 1;
- size_t size = hostLen + netInterfaceLen + sizeof(nsHostRecord);
+ size_t originSuffixLen = strlen(key->originSuffix) + 1;
+ size_t size = hostLen + netInterfaceLen + originSuffixLen + sizeof(nsHostRecord);
- // Use placement new to create the object with room for the hostname and
- // network interface name allocated after it.
+ // Use placement new to create the object with room for the hostname,
+ // network interface name and originSuffix allocated after it.
void *place = ::operator new(size);
*result = new(place) nsHostRecord(key);
NS_ADDREF(*result);
return NS_OK;
}
void
@@ -398,31 +402,32 @@ struct nsHostDBEnt : PLDHashEntryHdr
nsHostRecord *rec;
};
static PLDHashNumber
HostDB_HashKey(const void *key)
{
const nsHostKey *hk = static_cast<const nsHostKey *>(key);
return AddToHash(HashString(hk->host), RES_KEY_FLAGS(hk->flags), hk->af,
- HashString(hk->netInterface));
+ HashString(hk->netInterface), HashString(hk->originSuffix));
}
static bool
HostDB_MatchEntry(const PLDHashEntryHdr *entry,
const void *key)
{
const nsHostDBEnt *he = static_cast<const nsHostDBEnt *>(entry);
const nsHostKey *hk = static_cast<const nsHostKey *>(key);
return !strcmp(he->rec->host ? he->rec->host : "",
hk->host ? hk->host : "") &&
RES_KEY_FLAGS (he->rec->flags) == RES_KEY_FLAGS(hk->flags) &&
he->rec->af == hk->af &&
- !strcmp(he->rec->netInterface, hk->netInterface);
+ !strcmp(he->rec->netInterface, hk->netInterface) &&
+ !strcmp(he->rec->originSuffix, hk->originSuffix);
}
static void
HostDB_MoveEntry(PLDHashTable *table,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to)
{
static_cast<nsHostDBEnt *>(to)->rec =
@@ -717,21 +722,22 @@ nsHostResolver::MoveQueue(nsHostRecord *
{
NS_ASSERTION(aRec->onQueue, "Moving Host Record Not Currently Queued");
PR_REMOVE_LINK(aRec);
PR_APPEND_LINK(aRec, &aDestQ);
}
nsresult
-nsHostResolver::ResolveHost(const char *host,
- uint16_t flags,
- uint16_t af,
- const char *netInterface,
- nsResolveHostCallback *callback)
+nsHostResolver::ResolveHost(const char *host,
+ const OriginAttributes &aOriginAttributes,
+ uint16_t flags,
+ uint16_t af,
+ const char *netInterface,
+ nsResolveHostCallback *callback)
{
NS_ENSURE_TRUE(host && *host, NS_ERROR_UNEXPECTED);
NS_ENSURE_TRUE(netInterface, NS_ERROR_UNEXPECTED);
LOG(("Resolving host [%s%s%s]%s.\n", LOG_HOST(host, netInterface),
flags & RES_BYPASS_CACHE ? " - bypassing cache" : ""));
// ensure that we are working with a valid hostname before proceeding. see
@@ -756,18 +762,20 @@ nsHostResolver::ResolveHost(const char
memset(&tempAddr, 0, sizeof(PRNetAddr));
// check to see if there is already an entry for this |host|
// in the hash table. if so, then check to see if we can't
// just reuse the lookup result. otherwise, if there are
// any pending callbacks, then add to pending callbacks queue,
// and return. otherwise, add ourselves as first pending
// callback, and proceed to do the lookup.
+ nsAutoCString originSuffix;
+ aOriginAttributes.CreateSuffix(originSuffix);
- nsHostKey key = { host, flags, af, netInterface };
+ nsHostKey key = { host, flags, af, netInterface, originSuffix.get() };
auto he = static_cast<nsHostDBEnt*>(mDB.Add(&key, fallible));
// if the record is null, the hash table OOM'd.
if (!he) {
LOG((" Out of memory: no cache entry for host [%s%s%s].\n",
LOG_HOST(host, netInterface)));
rv = NS_ERROR_OUT_OF_MEMORY;
}
@@ -835,17 +843,17 @@ nsHostResolver::ResolveHost(const char
// If this is an IPV4 or IPV6 specific request, check if there is
// an AF_UNSPEC entry we can use. Otherwise, hit the resolver...
else if (!he->rec->resolving) {
if (!(flags & RES_BYPASS_CACHE) &&
((af == PR_AF_INET) || (af == PR_AF_INET6))) {
// First, search for an entry with AF_UNSPEC
const nsHostKey unspecKey = { host, flags, PR_AF_UNSPEC,
- netInterface };
+ netInterface, originSuffix.get() };
auto unspecHe =
static_cast<nsHostDBEnt*>(mDB.Search(&unspecKey));
NS_ASSERTION(!unspecHe ||
(unspecHe && unspecHe->rec),
"Valid host entries should contain a record");
TimeStamp now = TimeStamp::NowLoRes();
if (unspecHe &&
unspecHe->rec->HasUsableResult(now, flags)) {
@@ -963,28 +971,32 @@ nsHostResolver::ResolveHost(const char
if (result) {
callback->OnLookupComplete(this, result, status);
}
return rv;
}
void
-nsHostResolver::DetachCallback(const char *host,
- uint16_t flags,
- uint16_t af,
- const char *netInterface,
- nsResolveHostCallback *callback,
- nsresult status)
+nsHostResolver::DetachCallback(const char *host,
+ const OriginAttributes &aOriginAttributes,
+ uint16_t flags,
+ uint16_t af,
+ const char *netInterface,
+ nsResolveHostCallback *callback,
+ nsresult status)
{
RefPtr<nsHostRecord> rec;
{
MutexAutoLock lock(mLock);
- nsHostKey key = { host, flags, af, netInterface };
+ nsAutoCString originSuffix;
+ aOriginAttributes.CreateSuffix(originSuffix);
+
+ nsHostKey key = { host, flags, af, netInterface, originSuffix.get() };
auto he = static_cast<nsHostDBEnt*>(mDB.Search(&key));
if (he) {
// walk list looking for |callback|... we cannot assume
// that it will be there!
PRCList *node = he->rec->callbacks.next;
while (node != &he->rec->callbacks) {
if (static_cast<nsResolveHostCallback *>(node) == callback) {
PR_REMOVE_LINK(callback);
@@ -1366,28 +1378,32 @@ nsHostResolver::OnLookupComplete(nsHostR
}
NS_RELEASE(rec);
return LOOKUP_OK;
}
void
-nsHostResolver::CancelAsyncRequest(const char *host,
- uint16_t flags,
- uint16_t af,
- const char *netInterface,
- nsIDNSListener *aListener,
- nsresult status)
+nsHostResolver::CancelAsyncRequest(const char *host,
+ const OriginAttributes &aOriginAttributes,
+ uint16_t flags,
+ uint16_t af,
+ const char *netInterface,
+ nsIDNSListener *aListener,
+ nsresult status)
{
MutexAutoLock lock(mLock);
+ nsAutoCString originSuffix;
+ aOriginAttributes.CreateSuffix(originSuffix);
+
// Lookup the host record associated with host, flags & address family
- nsHostKey key = { host, flags, af, netInterface };
+ nsHostKey key = { host, flags, af, netInterface, originSuffix.get() };
auto he = static_cast<nsHostDBEnt*>(mDB.Search(&key));
if (he) {
nsHostRecord* recPtr = nullptr;
PRCList *node = he->rec->callbacks.next;
// Remove the first nsDNSAsyncRequest callback which matches the
// supplied listener object
while (node != &he->rec->callbacks) {
nsResolveHostCallback *callback
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -34,16 +34,17 @@ class nsResolveHostCallback;
MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)
struct nsHostKey
{
const char *host;
uint16_t flags;
uint16_t af;
const char *netInterface;
+ const char *originSuffix;
};
/**
* nsHostRecord - ref counted object type stored in host resolver cache.
*/
class nsHostRecord : public PRCList, public nsHostKey
{
typedef mozilla::Mutex Mutex;
@@ -229,54 +230,57 @@ public:
/**
* puts the resolver in the shutdown state, which will cause any pending
* callbacks to be detached. any future calls to ResolveHost will fail.
*/
void Shutdown();
/**
- * resolve the given hostname asynchronously. the caller can synthesize
- * a synchronous host lookup using a lock and a cvar. as noted above
- * the callback will occur re-entrantly from an unspecified thread. the
- * host lookup cannot be canceled (cancelation can be layered above this
- * by having the callback implementation return without doing anything).
+ * resolve the given hostname and originAttributes asynchronously. the caller
+ * can synthesize a synchronous host lookup using a lock and a cvar. as noted
+ * above the callback will occur re-entrantly from an unspecified thread. the
+ * host lookup cannot be canceled (cancelation can be layered above this by
+ * having the callback implementation return without doing anything).
*/
- nsresult ResolveHost(const char *hostname,
- uint16_t flags,
- uint16_t af,
- const char *netInterface,
- nsResolveHostCallback *callback);
+ nsresult ResolveHost(const char *hostname,
+ const mozilla::OriginAttributes &aOriginAttributes,
+ uint16_t flags,
+ uint16_t af,
+ const char *netInterface,
+ nsResolveHostCallback *callback);
/**
* removes the specified callback from the nsHostRecord for the given
- * hostname, flags, and address family. these parameters should correspond
- * to the parameters passed to ResolveHost. this function executes the
- * callback if the callback is still pending with the given status.
+ * hostname, originAttributes, flags, and address family. these parameters
+ * should correspond to the parameters passed to ResolveHost. this function
+ * executes the callback if the callback is still pending with the given status.
*/
- void DetachCallback(const char *hostname,
- uint16_t flags,
- uint16_t af,
- const char *netInterface,
- nsResolveHostCallback *callback,
- nsresult status);
+ void DetachCallback(const char *hostname,
+ const mozilla::OriginAttributes &aOriginAttributes,
+ uint16_t flags,
+ uint16_t af,
+ const char *netInterface,
+ nsResolveHostCallback *callback,
+ nsresult status);
/**
- * Cancels an async request associated with the hostname, flags,
+ * Cancels an async request associated with the hostname, originAttributes, flags,
* address family and listener. Cancels first callback found which matches
* these criteria. These parameters should correspond to the parameters
* passed to ResolveHost. If this is the last callback associated with the
* host record, it is removed from any request queues it might be on.
*/
- void CancelAsyncRequest(const char *host,
- uint16_t flags,
- uint16_t af,
- const char *netInterface,
- nsIDNSListener *aListener,
- nsresult status);
+ void CancelAsyncRequest(const char *host,
+ const mozilla::OriginAttributes &aOriginAttributes,
+ uint16_t flags,
+ uint16_t af,
+ const char *netInterface,
+ nsIDNSListener *aListener,
+ nsresult status);
/**
* values for the flags parameter passed to ResolveHost and DetachCallback
* that may be bitwise OR'd together.
*
* NOTE: in this implementation, these flags correspond exactly in value
* to the flags defined on nsIDNSService.
*/
enum {
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -293,16 +293,17 @@ NeckoChild::DeallocPUDPSocketChild(PUDPS
UDPSocketChild* p = static_cast<UDPSocketChild*>(child);
p->ReleaseIPDLReference();
return true;
}
PDNSRequestChild*
NeckoChild::AllocPDNSRequestChild(const nsCString& aHost,
+ const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags,
const nsCString& aNetworkInterface)
{
// We don't allocate here: instead we always use IPDL constructor that takes
// an existing object
NS_NOTREACHED("AllocPDNSRequestChild should not be called on child");
return nullptr;
}
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -54,16 +54,17 @@ protected:
AllocPTCPServerSocketChild(const uint16_t& aLocalPort,
const uint16_t& aBacklog,
const bool& aUseArrayBuffers) override;
virtual bool DeallocPTCPServerSocketChild(PTCPServerSocketChild*) override;
virtual PUDPSocketChild* AllocPUDPSocketChild(const Principal& aPrincipal,
const nsCString& aFilter) override;
virtual bool DeallocPUDPSocketChild(PUDPSocketChild*) override;
virtual PDNSRequestChild* AllocPDNSRequestChild(const nsCString& aHost,
+ const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags,
const nsCString& aNetworkInterface) override;
virtual bool DeallocPDNSRequestChild(PDNSRequestChild*) override;
virtual PDataChannelChild* AllocPDataChannelChild(const uint32_t& channelId) override;
virtual bool DeallocPDataChannelChild(PDataChannelChild* child) override;
virtual PRtspControllerChild* AllocPRtspControllerChild() override;
virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) override;
virtual PRtspChannelChild*
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -630,31 +630,35 @@ NeckoParent::DeallocPUDPSocketParent(PUD
{
UDPSocketParent* p = static_cast<UDPSocketParent*>(actor);
p->Release();
return true;
}
PDNSRequestParent*
NeckoParent::AllocPDNSRequestParent(const nsCString& aHost,
+ const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags,
const nsCString& aNetworkInterface)
{
DNSRequestParent *p = new DNSRequestParent();
p->AddRef();
return p;
}
mozilla::ipc::IPCResult
NeckoParent::RecvPDNSRequestConstructor(PDNSRequestParent* aActor,
const nsCString& aHost,
+ const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags,
const nsCString& aNetworkInterface)
{
- static_cast<DNSRequestParent*>(aActor)->DoAsyncResolve(aHost, aFlags,
+ static_cast<DNSRequestParent*>(aActor)->DoAsyncResolve(aHost,
+ aOriginAttributes,
+ aFlags,
aNetworkInterface);
return IPC_OK();
}
bool
NeckoParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent)
{
DNSRequestParent *p = static_cast<DNSRequestParent*>(aParent);
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -144,20 +144,22 @@ protected:
virtual bool DeallocPTCPServerSocketParent(PTCPServerSocketParent*) override;
virtual PUDPSocketParent* AllocPUDPSocketParent(const Principal& aPrincipal,
const nsCString& aFilter) override;
virtual mozilla::ipc::IPCResult RecvPUDPSocketConstructor(PUDPSocketParent*,
const Principal& aPrincipal,
const nsCString& aFilter) override;
virtual bool DeallocPUDPSocketParent(PUDPSocketParent*) override;
virtual PDNSRequestParent* AllocPDNSRequestParent(const nsCString& aHost,
+ const OriginAttributes& aOriginAttributes,
const uint32_t& aFlags,
const nsCString& aNetworkInterface) override;
virtual mozilla::ipc::IPCResult RecvPDNSRequestConstructor(PDNSRequestParent* actor,
const nsCString& hostName,
+ const OriginAttributes& aOriginAttributes,
const uint32_t& flags,
const nsCString& aNetworkInterface) override;
virtual bool DeallocPDNSRequestParent(PDNSRequestParent*) override;
virtual mozilla::ipc::IPCResult RecvSpeculativeConnect(const URIParams& aURI,
const Principal& aPrincipal,
const bool& aAnonymous) override;
virtual mozilla::ipc::IPCResult RecvHTMLDNSPrefetch(const nsString& hostname,
const uint16_t& flags) override;