author | Tim Huang <tihuang@mozilla.com> |
Tue, 14 Feb 2017 12:25:35 +0800 (2017-02-14) | |
changeset 346140 | 7405ef5589cc1f141c22bc2de596c010be4d6c17 |
parent 346139 | b8ee0c21d462cfeb8a549785dd7c0cd0bbdbf3b4 |
child 346141 | a98c0d18ca5e674181625cbe6c07c5c85853c0f2 |
push id | 31459 |
push user | cbook@mozilla.com |
push date | Tue, 07 Mar 2017 14:05:14 +0000 (2017-03-07) |
treeherder | mozilla-central@1fb56ba248d5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | valentin |
bugs | 1337893 |
milestone | 54.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- 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;