From 3b0bd1832e7387cd25c8feb0c8224f06bf792793 Mon Sep 17 00:00:00 2001 From: Jason Duell Date: Wed, 11 Dec 2013 11:03:51 -0800 Subject: [PATCH] Bug 945066: remote nsIDNSService to child. r=jdm * * * bug 945066. Fix windows bustage. r=jduell --- netwerk/build/nsNetModule.cpp | 10 +- netwerk/dns/ChildDNSService.cpp | 231 ++++++++++++++++ netwerk/dns/ChildDNSService.h | 42 +++ netwerk/dns/DNS.cpp | 26 ++ netwerk/dns/DNS.h | 3 + netwerk/dns/DNSListenerProxy.cpp | 36 +++ netwerk/dns/DNSListenerProxy.h | 66 +++++ netwerk/dns/DNSRequestChild.cpp | 247 ++++++++++++++++++ netwerk/dns/DNSRequestChild.h | 58 ++++ netwerk/dns/DNSRequestParent.cpp | 105 ++++++++ netwerk/dns/DNSRequestParent.h | 39 +++ netwerk/dns/PDNSParams.h | 23 ++ netwerk/dns/PDNSRequest.ipdl | 31 +++ netwerk/dns/PDNSRequestParams.ipdlh | 31 +++ netwerk/dns/moz.build | 16 ++ netwerk/dns/nsDNSService2.cpp | 108 +++----- netwerk/dns/nsDNSService2.h | 6 + netwerk/dns/nsEffectiveTLDService.h | 5 + netwerk/dns/nsHostResolver.cpp | 6 +- netwerk/ipc/NeckoChild.cpp | 19 ++ netwerk/ipc/NeckoChild.h | 3 + netwerk/ipc/NeckoParent.cpp | 27 ++ netwerk/ipc/NeckoParent.h | 6 + netwerk/ipc/PNecko.ipdl | 4 + .../test/unit_ipc/test_dns_service_wrap.js | 7 + netwerk/test/unit_ipc/xpcshell.ini | 1 + 26 files changed, 1084 insertions(+), 72 deletions(-) create mode 100644 netwerk/dns/ChildDNSService.cpp create mode 100644 netwerk/dns/ChildDNSService.h create mode 100644 netwerk/dns/DNSListenerProxy.cpp create mode 100644 netwerk/dns/DNSListenerProxy.h create mode 100644 netwerk/dns/DNSRequestChild.cpp create mode 100644 netwerk/dns/DNSRequestChild.h create mode 100644 netwerk/dns/DNSRequestParent.cpp create mode 100644 netwerk/dns/DNSRequestParent.h create mode 100644 netwerk/dns/PDNSParams.h create mode 100644 netwerk/dns/PDNSRequest.ipdl create mode 100644 netwerk/dns/PDNSRequestParams.ipdlh create mode 100644 netwerk/test/unit_ipc/test_dns_service_wrap.js diff --git a/netwerk/build/nsNetModule.cpp b/netwerk/build/nsNetModule.cpp index aac04aefc75..e232e0635b8 100644 --- a/netwerk/build/nsNetModule.cpp +++ b/netwerk/build/nsNetModule.cpp @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set sw=4 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/. */ @@ -57,8 +58,9 @@ NS_HIDDEN_(ContentSnifferCache*) gDataSniffers = nullptr; NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIOService, nsIOService::GetInstance) #include "nsDNSService2.h" -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDNSService, Init) - +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIDNSService, + nsDNSService::GetXPCOMSingleton) + #include "nsProtocolProxyService.h" NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsProtocolProxyService, Init) @@ -825,7 +827,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = { { &kNS_SERVERSOCKET_CID, false, nullptr, nsServerSocketConstructor }, { &kNS_UDPSOCKET_CID, false, nullptr, nsUDPSocketConstructor }, { &kNS_SOCKETPROVIDERSERVICE_CID, false, nullptr, nsSocketProviderService::Create }, - { &kNS_DNSSERVICE_CID, false, nullptr, nsDNSServiceConstructor }, + { &kNS_DNSSERVICE_CID, false, nullptr, nsIDNSServiceConstructor }, { &kNS_IDNSERVICE_CID, false, nullptr, nsIDNServiceConstructor }, { &kNS_EFFECTIVETLDSERVICE_CID, false, nullptr, nsEffectiveTLDServiceConstructor }, { &kNS_SIMPLEURI_CID, false, nullptr, nsSimpleURIConstructor }, diff --git a/netwerk/dns/ChildDNSService.cpp b/netwerk/dns/ChildDNSService.cpp new file mode 100644 index 00000000000..52463cb28c5 --- /dev/null +++ b/netwerk/dns/ChildDNSService.cpp @@ -0,0 +1,231 @@ +/* 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 "nsNetUtil.h" +#include "nsIThread.h" +#include "nsThreadUtils.h" +#include "nsIXPConnect.h" +#include "nsIPrefService.h" +#include "nsIProtocolProxyService.h" +#include "mozilla/net/NeckoChild.h" +#include "mozilla/net/DNSRequestChild.h" +#include "mozilla/net/DNSListenerProxy.h" + +namespace mozilla { +namespace net { + +//----------------------------------------------------------------------------- +// ChildDNSService +//----------------------------------------------------------------------------- + +static ChildDNSService *gChildDNSService; +static const char kPrefNameDisablePrefetch[] = "network.dns.disablePrefetch"; + +ChildDNSService* ChildDNSService::GetSingleton() +{ + MOZ_ASSERT(IsNeckoChild()); + + if (!gChildDNSService) { + gChildDNSService = new ChildDNSService(); + } + + NS_ADDREF(gChildDNSService); + return gChildDNSService; +} + +NS_IMPL_ISUPPORTS3(ChildDNSService, + nsIDNSService, + nsPIDNSService, + nsIObserver) + +ChildDNSService::ChildDNSService() + : mFirstTime(true) + , mOffline(false) +{ + MOZ_ASSERT(IsNeckoChild()); +} + +ChildDNSService::~ChildDNSService() +{ + +} + +//----------------------------------------------------------------------------- +// ChildDNSService::nsIDNSService +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +ChildDNSService::AsyncResolve(const nsACString &hostname, + uint32_t flags, + nsIDNSListener *listener, + nsIEventTarget *target_, + nsICancelable **result) +{ + NS_ENSURE_TRUE(gNeckoChild != nullptr, NS_ERROR_FAILURE); + + if (mDisablePrefetch && (flags & RESOLVE_SPECULATE)) { + return NS_ERROR_DNS_LOOKUP_QUEUE_FULL; + } + + // Support apps being 'offline' even if parent is not: avoids DNS traffic by + // apps that have been told they are offline. + if (mOffline) { + flags |= RESOLVE_OFFLINE; + } + + // make sure JS callers get notification on the main thread + nsCOMPtr target = target_; + nsCOMPtr wrappedListener = do_QueryInterface(listener); + if (wrappedListener && !target) { + nsCOMPtr mainThread; + NS_GetMainThread(getter_AddRefs(mainThread)); + target = do_QueryInterface(mainThread); + } + 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); + } + + nsRefPtr childReq = + new DNSRequestChild(nsCString(hostname), flags, listener, target); + + childReq->StartRequest(); + + childReq.forget(result); + return NS_OK; +} + +NS_IMETHODIMP +ChildDNSService::CancelAsyncResolve(const nsACString &aHostname, + uint32_t aFlags, + nsIDNSListener *aListener, + nsresult aReason) +{ + if (mDisablePrefetch && (aFlags & RESOLVE_SPECULATE)) { + return NS_ERROR_DNS_LOOKUP_QUEUE_FULL; + } + + // TODO: keep a hashtable of pending requests, so we can obey cancel semantics + // (call OnLookupComplete with aReason). Also possible we could send IPDL to + // parent to cancel. + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +ChildDNSService::Resolve(const nsACString &hostname, + uint32_t flags, + nsIDNSRecord **result) +{ + // not planning to ever support this, since sync IPDL is evil. + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +ChildDNSService::GetDNSCacheEntries(nsTArray *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::GetMyHostName(nsACString &result) +{ + // TODO: get value from parent during PNecko construction? + return NS_ERROR_NOT_AVAILABLE; +} + +//----------------------------------------------------------------------------- +// 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 prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); + prefs->GetBoolPref(kPrefNameDisablePrefetch, &disablePrefetch); + 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; +} + +NS_IMETHODIMP +ChildDNSService::GetOffline(bool* aResult) +{ + *aResult = mOffline; + return NS_OK; +} + +NS_IMETHODIMP +ChildDNSService::SetOffline(bool value) +{ + mOffline = value; + return NS_OK; +} + +//----------------------------------------------------------------------------- +// ChildDNSService::nsIObserver +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +ChildDNSService::Observe(nsISupports *subject, const char *topic, + const PRUnichar *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 diff --git a/netwerk/dns/ChildDNSService.h b/netwerk/dns/ChildDNSService.h new file mode 100644 index 00000000000..d4df63a0d45 --- /dev/null +++ b/netwerk/dns/ChildDNSService.h @@ -0,0 +1,42 @@ +/* -*- 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/. */ + +#ifndef mozilla_net_ChildDNSService_h +#define mozilla_net_ChildDNSService_h + + +#include "nsPIDNSService.h" +#include "nsIObserver.h" +#include "mozilla/Attributes.h" + +namespace mozilla { +namespace net { + +class ChildDNSService MOZ_FINAL + : public nsPIDNSService + , public nsIObserver +{ +public: + // AsyncResolve (and CancelAsyncResolve) can be called off-main + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSPIDNSSERVICE + NS_DECL_NSIDNSSERVICE + NS_DECL_NSIOBSERVER + + ChildDNSService(); + virtual ~ChildDNSService(); + + static ChildDNSService* GetSingleton(); + +private: + bool mFirstTime; + bool mOffline; + bool mDisablePrefetch; +}; + +} // namespace net +} // namespace mozilla +#endif // mozilla_net_ChildDNSService_h diff --git a/netwerk/dns/DNS.cpp b/netwerk/dns/DNS.cpp index d1835549dab..24e4fa62c37 100644 --- a/netwerk/dns/DNS.cpp +++ b/netwerk/dns/DNS.cpp @@ -6,6 +6,7 @@ #include "mozilla/Assertions.h" #include "mozilla/mozalloc.h" +#include "mozilla/ArrayUtils.h" #include #ifdef XP_WIN @@ -203,6 +204,31 @@ bool IsIPAddrLocal(const NetAddr *addr) return false; } +bool +NetAddr::operator == (const NetAddr& other) const +{ + if (this->raw.family != other.raw.family) { + return false; + } else if (this->raw.family == AF_INET) { + return (this->inet.port == other.inet.port) && + (this->inet.ip == other.inet.ip); + } else if (this->raw.family == AF_INET6) { + return (this->inet6.port == other.inet6.port) && + (this->inet6.flowinfo == other.inet6.flowinfo) && + (memcmp(&this->inet6.ip, &other.inet6.ip, + sizeof(this->inet6.ip)) == 0) && + (this->inet6.scope_id == other.inet6.scope_id); +#if defined(XP_UNIX) || defined(XP_OS2) + } else if (this->raw.family == AF_LOCAL) { + return PL_strncmp(this->local.path, other.local.path, + ArrayLength(this->local.path)); +#endif + } + return false; +} + + + NetAddrElement::NetAddrElement(const PRNetAddr *prNetAddr) { PRNetAddrToNetAddr(prNetAddr, &mAddress); diff --git a/netwerk/dns/DNS.h b/netwerk/dns/DNS.h index 1fe42e08d85..8375b551937 100644 --- a/netwerk/dns/DNS.h +++ b/netwerk/dns/DNS.h @@ -10,6 +10,7 @@ #include "nscore.h" #include "prio.h" #include "prnetdb.h" +#include "plstr.h" #include "mozilla/LinkedList.h" #include "mozilla/MemoryReporting.h" @@ -112,6 +113,8 @@ union NetAddr { #endif } local; #endif + // introduced to support nsTArray (for DNSRequestParent.cpp) + bool operator == (const NetAddr& other) const; }; // This class wraps a NetAddr union to provide C++ linked list diff --git a/netwerk/dns/DNSListenerProxy.cpp b/netwerk/dns/DNSListenerProxy.cpp new file mode 100644 index 00000000000..d3e252fc5e4 --- /dev/null +++ b/netwerk/dns/DNSListenerProxy.cpp @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set sw=4 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/. */ + +#include "mozilla/net/DNSListenerProxy.h" +#include "nsICancelable.h" +#include "nsIEventTarget.h" + +namespace mozilla { +namespace net { + +NS_IMPL_ISUPPORTS1(DNSListenerProxy, nsIDNSListener) + +NS_IMETHODIMP +DNSListenerProxy::OnLookupComplete(nsICancelable* aRequest, + nsIDNSRecord* aRecord, + nsresult aStatus) +{ + nsRefPtr r = + new OnLookupCompleteRunnable(mListener, aRequest, aRecord, aStatus); + return mTargetThread->Dispatch(r, NS_DISPATCH_NORMAL); +} + +NS_IMETHODIMP +DNSListenerProxy::OnLookupCompleteRunnable::Run() +{ + mListener->OnLookupComplete(mRequest, mRecord, mStatus); + return NS_OK; +} + + + +} // namespace net +} // namespace mozilla diff --git a/netwerk/dns/DNSListenerProxy.h b/netwerk/dns/DNSListenerProxy.h new file mode 100644 index 00000000000..32065c5f94d --- /dev/null +++ b/netwerk/dns/DNSListenerProxy.h @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set sw=4 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/. */ + +#ifndef DNSListenerProxy_h__ +#define DNSListenerProxy_h__ + +#include "nsIDNSListener.h" +#include "nsIDNSRecord.h" +#include "nsProxyRelease.h" +#include "nsThreadUtils.h" + +class nsIEventTarget; +class nsICancelable; + +namespace mozilla { +namespace net { + +class DNSListenerProxy MOZ_FINAL : public nsIDNSListener +{ +public: + DNSListenerProxy(nsIDNSListener* aListener, nsIEventTarget* aTargetThread) + // Sometimes aListener is a main-thread only object like XPCWrappedJS, and + // sometimes it's a threadsafe object like nsSOCKSSocketInfo. Use a main- + // thread pointer holder, but disable strict enforcement of thread invariants. + // The AddRef implementation of XPCWrappedJS will assert if we go wrong here. + : mListener(new nsMainThreadPtrHolder(aListener, false)) + , mTargetThread(aTargetThread) + { } + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIDNSLISTENER + + class OnLookupCompleteRunnable : public nsRunnable + { + public: + OnLookupCompleteRunnable(const nsMainThreadPtrHandle& aListener, + nsICancelable* aRequest, + nsIDNSRecord* aRecord, + nsresult aStatus) + : mListener(aListener) + , mRequest(aRequest) + , mRecord(aRecord) + , mStatus(aStatus) + { } + + NS_DECL_NSIRUNNABLE + + private: + nsMainThreadPtrHandle mListener; + nsCOMPtr mRequest; + nsCOMPtr mRecord; + nsresult mStatus; + }; + +private: + nsMainThreadPtrHandle mListener; + nsCOMPtr mTargetThread; +}; + + +} // namespace net +} // namespace mozilla +#endif // DNSListenerProxy_h__ diff --git a/netwerk/dns/DNSRequestChild.cpp b/netwerk/dns/DNSRequestChild.cpp new file mode 100644 index 00000000000..b1f2a449eb5 --- /dev/null +++ b/netwerk/dns/DNSRequestChild.cpp @@ -0,0 +1,247 @@ +/* -*- 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/. */ + +#include "mozilla/net/DNSRequestChild.h" +#include "mozilla/net/NeckoChild.h" +#include "nsIDNSRecord.h" +#include "nsHostResolver.h" +#include "nsTArray.h" +#include "nsNetAddr.h" +#include "nsIThread.h" +#include "nsThreadUtils.h" + +using namespace mozilla::ipc; + +namespace mozilla { +namespace net { + +//----------------------------------------------------------------------------- +// ChildDNSRecord: +// A simple class to provide nsIDNSRecord on the child +//----------------------------------------------------------------------------- + +class ChildDNSRecord : public nsIDNSRecord +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIDNSRECORD + + ChildDNSRecord(const DNSRecord& reply, uint16_t flags); + virtual ~ChildDNSRecord(); + +private: + nsCString mCanonicalName; + nsTArray mAddresses; + uint32_t mCurrent; // addr iterator + uint32_t mLength; // number of addrs + uint16_t mFlags; +}; + +NS_IMPL_ISUPPORTS1(ChildDNSRecord, nsIDNSRecord) + +ChildDNSRecord::ChildDNSRecord(const DNSRecord& reply, uint16_t flags) + : mCurrent(0) + , mFlags(flags) +{ + mCanonicalName = reply.canonicalName(); + + // A shame IPDL gives us no way to grab ownership of array: so copy it. + const nsTArray& addrs = reply.addrs(); + uint32_t i = 0; + mLength = addrs.Length(); + for (; i < mLength; i++) { + mAddresses.AppendElement(addrs[i]); + } +} + +ChildDNSRecord::~ChildDNSRecord() +{ +} + +//----------------------------------------------------------------------------- +// ChildDNSRecord::nsIDNSRecord +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +ChildDNSRecord::GetCanonicalName(nsACString &result) +{ + if (!(mFlags & nsHostResolver::RES_CANON_NAME)) { + return NS_ERROR_NOT_AVAILABLE; + } + + result = mCanonicalName; + return NS_OK; +} + +NS_IMETHODIMP +ChildDNSRecord::GetNextAddr(uint16_t port, NetAddr *addr) +{ + if (mCurrent >= mLength) { + return NS_ERROR_NOT_AVAILABLE; + } + + memcpy(addr, &mAddresses[mCurrent++], sizeof(NetAddr)); + + // both Ipv4/6 use same bits for port, so safe to just use ipv4's field + addr->inet.port = port; + + return NS_OK; +} + +// shamelessly copied from nsDNSRecord +NS_IMETHODIMP +ChildDNSRecord::GetScriptableNextAddr(uint16_t port, nsINetAddr **result) +{ + NetAddr addr; + nsresult rv = GetNextAddr(port, &addr); + if (NS_FAILED(rv)) return rv; + + NS_ADDREF(*result = new nsNetAddr(&addr)); + + return NS_OK; +} + +// also copied from nsDNSRecord +NS_IMETHODIMP +ChildDNSRecord::GetNextAddrAsString(nsACString &result) +{ + NetAddr addr; + nsresult rv = GetNextAddr(0, &addr); + if (NS_FAILED(rv)) { + return rv; + } + + char buf[kIPv6CStrBufSize]; + if (NetAddrToString(&addr, buf, sizeof(buf))) { + result.Assign(buf); + return NS_OK; + } + NS_ERROR("NetAddrToString failed unexpectedly"); + return NS_ERROR_FAILURE; // conversion failed for some reason +} + +NS_IMETHODIMP +ChildDNSRecord::HasMore(bool *result) +{ + *result = mCurrent < mLength; + return NS_OK; +} + +NS_IMETHODIMP +ChildDNSRecord::Rewind() +{ + mCurrent = 0; + return NS_OK; +} + +NS_IMETHODIMP +ChildDNSRecord::ReportUnusable(uint16_t aPort) +{ + // "We thank you for your feedback" == >/dev/null + // TODO: we could send info back to parent. + return NS_OK; +} + +//----------------------------------------------------------------------------- +// DNSRequestChild +//----------------------------------------------------------------------------- + +DNSRequestChild::DNSRequestChild(const nsCString& aHost, + const uint32_t& aFlags, + nsIDNSListener *aListener, + nsIEventTarget *target) + : mListener(aListener) + , mTarget(target) + , mResultStatus(NS_OK) + , mHost(aHost) + , mFlags(aFlags) +{ +} + +void +DNSRequestChild::StartRequest() +{ + // we can only do IPDL on the main thread + if (!NS_IsMainThread()) { + NS_DispatchToMainThread( + NS_NewRunnableMethod(this, &DNSRequestChild::StartRequest)); + return; + } + + // Send request to Parent process. + gNeckoChild->SendPDNSRequestConstructor(this, mHost, mFlags); + + // IPDL holds a reference until IPDL channel gets destroyed + AddIPDLReference(); +} + +void +DNSRequestChild::CallOnLookupComplete() +{ + MOZ_ASSERT(mListener); + + mListener->OnLookupComplete(this, mResultRecord, mResultStatus); +} + +bool +DNSRequestChild::Recv__delete__(const DNSRequestResponse& reply) +{ + MOZ_ASSERT(mListener); + + switch (reply.type()) { + case DNSRequestResponse::TDNSRecord: { + mResultRecord = new ChildDNSRecord(reply.get_DNSRecord(), mFlags); + break; + } + case DNSRequestResponse::Tnsresult: { + mResultStatus = reply.get_nsresult(); + break; + } + default: + NS_NOTREACHED("unknown type"); + return false; + } + + MOZ_ASSERT(NS_IsMainThread()); + + bool targetIsMain = false; + if (!mTarget) { + targetIsMain = true; + } else { + mTarget->IsOnCurrentThread(&targetIsMain); + } + + if (targetIsMain) { + CallOnLookupComplete(); + } else { + nsCOMPtr event = + NS_NewRunnableMethod(this, &DNSRequestChild::CallOnLookupComplete); + mTarget->Dispatch(event, NS_DISPATCH_NORMAL); + } + + return true; +} + +//----------------------------------------------------------------------------- +// DNSRequestChild::nsISupports +//----------------------------------------------------------------------------- + +NS_IMPL_ISUPPORTS1(DNSRequestChild, + nsICancelable) + +//----------------------------------------------------------------------------- +// DNSRequestChild::nsICancelable +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +DNSRequestChild::Cancel(nsresult reason) +{ + // for now Cancel is a no-op + return NS_OK; +} + +//------------------------------------------------------------------------------ +}} // mozilla::net diff --git a/netwerk/dns/DNSRequestChild.h b/netwerk/dns/DNSRequestChild.h new file mode 100644 index 00000000000..157b1d0a2ed --- /dev/null +++ b/netwerk/dns/DNSRequestChild.h @@ -0,0 +1,58 @@ +/* -*- 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/. */ + +#ifndef mozilla_net_DNSRequestChild_h +#define mozilla_net_DNSRequestChild_h + +#include "mozilla/net/PDNSRequestChild.h" +#include "nsICancelable.h" +#include "nsIDNSRecord.h" +#include "nsIDNSListener.h" +#include "nsIEventTarget.h" + +namespace mozilla { +namespace net { + +class DNSRequestChild + : public PDNSRequestChild + , public nsICancelable +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSICANCELABLE + + DNSRequestChild(const nsCString& aHost, const uint32_t& aFlags, + nsIDNSListener *aListener, nsIEventTarget *target); + virtual ~DNSRequestChild() {} + + void AddIPDLReference() { + AddRef(); + } + void ReleaseIPDLReference() { + // we don't need an 'mIPCOpen' variable until/unless we add calls that might + // try to send IPDL msgs to parent after ReleaseIPDLReference is called + // (when IPDL channel torn down). + Release(); + } + + // Sends IPDL request to parent + void StartRequest(); + void CallOnLookupComplete(); + +private: + virtual bool Recv__delete__(const DNSRequestResponse& reply) MOZ_OVERRIDE; + + nsCOMPtr mListener; + nsCOMPtr mTarget; + nsCOMPtr mResultRecord; + nsresult mResultStatus; + nsCString mHost; + uint16_t mFlags; +}; + +} // namespace net +} // namespace mozilla +#endif // mozilla_net_DNSRequestChild_h diff --git a/netwerk/dns/DNSRequestParent.cpp b/netwerk/dns/DNSRequestParent.cpp new file mode 100644 index 00000000000..5561671617f --- /dev/null +++ b/netwerk/dns/DNSRequestParent.cpp @@ -0,0 +1,105 @@ +/* -*- 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/. */ + +#include "mozilla/net/DNSRequestParent.h" +#include "nsIDNSService.h" +#include "nsNetCID.h" +#include "nsThreadUtils.h" +#include "nsIServiceManager.h" +#include "nsICancelable.h" +#include "nsIDNSRecord.h" +#include "nsHostResolver.h" +#include "mozilla/unused.h" + +using namespace mozilla::ipc; + +namespace mozilla { +namespace net { + +DNSRequestParent::DNSRequestParent() + : mIPCClosed(false) +{ + +} + +DNSRequestParent::~DNSRequestParent() +{ + +} + +void +DNSRequestParent::DoAsyncResolve(const nsACString &hostname, uint32_t flags) +{ + nsresult rv; + mFlags = flags; + nsCOMPtr dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr mainThread = do_GetMainThread(); + nsCOMPtr unused; + rv = dns->AsyncResolve(hostname, flags, this, mainThread, + getter_AddRefs(unused)); + } + + if (NS_FAILED(rv) && !mIPCClosed) { + unused << Send__delete__(this, DNSRequestResponse(rv)); + } +} + +void +DNSRequestParent::ActorDestroy(ActorDestroyReason why) +{ + // We may still have refcount>0 if DNS hasn't called our OnLookupComplete + // yet, but child process has crashed. We must not send any more msgs + // to child, or IPDL will kill chrome process, too. + mIPCClosed = true; +} +//----------------------------------------------------------------------------- +// DNSRequestParent::nsISupports +//----------------------------------------------------------------------------- + +NS_IMPL_ISUPPORTS1(DNSRequestParent, + nsIDNSListener) + +//----------------------------------------------------------------------------- +// nsIDNSListener functions +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +DNSRequestParent::OnLookupComplete(nsICancelable *request, + nsIDNSRecord *rec, + nsresult status) +{ + if (mIPCClosed) { + // nothing to do: child probably crashed + return NS_OK; + } + + if (NS_SUCCEEDED(status)) { + MOZ_ASSERT(rec); + + nsAutoCString cname; + if (mFlags & nsHostResolver::RES_CANON_NAME) { + rec->GetCanonicalName(cname); + } + + // Get IP addresses for hostname (use port 80 as dummy value for NetAddr) + NetAddrArray array; + NetAddr addr; + while (NS_SUCCEEDED(rec->GetNextAddr(80, &addr))) { + array.AppendElement(addr); + } + + unused << Send__delete__(this, DNSRequestResponse(DNSRecord(cname, array))); + } else { + unused << Send__delete__(this, DNSRequestResponse(status)); + } + + return NS_OK; +} + + + +}} // mozilla::net diff --git a/netwerk/dns/DNSRequestParent.h b/netwerk/dns/DNSRequestParent.h new file mode 100644 index 00000000000..cfb4ecbb4cb --- /dev/null +++ b/netwerk/dns/DNSRequestParent.h @@ -0,0 +1,39 @@ +/* -*- 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/. */ + +#ifndef mozilla_net_DNSRequestParent_h +#define mozilla_net_DNSRequestParent_h + +#include "mozilla/net/PDNSRequestParent.h" +#include "nsIDNSService.h" +#include "nsIDNSListener.h" + +namespace mozilla { +namespace net { + +class DNSRequestParent + : public PDNSRequestParent + , public nsIDNSListener +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDNSLISTENER + + DNSRequestParent(); + virtual ~DNSRequestParent(); + + void DoAsyncResolve(const nsACString &hostname, uint32_t flags); + +protected: + virtual void ActorDestroy(ActorDestroyReason why); +private: + uint32_t mFlags; + bool mIPCClosed; // true if IPDL channel has been closed (child crash) +}; + +} // namespace net +} // namespace mozilla +#endif // mozilla_net_DNSRequestParent_h diff --git a/netwerk/dns/PDNSParams.h b/netwerk/dns/PDNSParams.h new file mode 100644 index 00000000000..e5e668164ce --- /dev/null +++ b/netwerk/dns/PDNSParams.h @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 ft=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/. */ + +#ifndef PDNSParams_h +#define PDNSParams_h + +#include "DNS.h" +#include "nsTArray.h" + +namespace mozilla { +namespace net { + +// Need to define typedef in .h file--can't seem to in ipdl.h file? +typedef nsTArray NetAddrArray; + +} // namespace net +} // namespace mozilla + +#endif // PDNSParams_h diff --git a/netwerk/dns/PDNSRequest.ipdl b/netwerk/dns/PDNSRequest.ipdl new file mode 100644 index 00000000000..b8a201ad674 --- /dev/null +++ b/netwerk/dns/PDNSRequest.ipdl @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */ + +/* 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 protocol PNecko; + +include PDNSRequestParams; + +include "mozilla/net/NeckoMessageUtils.h"; + +namespace mozilla { +namespace net { + +async protocol PDNSRequest +{ + manager PNecko; + +//parent: + // constructor in PNecko takes AsyncResolve args that initialize request + + +child: + __delete__(DNSRequestResponse reply); + +}; + +} //namespace net +} //namespace mozilla diff --git a/netwerk/dns/PDNSRequestParams.ipdlh b/netwerk/dns/PDNSRequestParams.ipdlh new file mode 100644 index 00000000000..d06f27cfa2d --- /dev/null +++ b/netwerk/dns/PDNSRequestParams.ipdlh @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */ + +/* 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/. */ + +using NetAddrArray from "mozilla/net/PDNSParams.h"; + +namespace mozilla { +namespace net { + +//----------------------------------------------------------------------------- +// DNS IPDL structs +//----------------------------------------------------------------------------- + +struct DNSRecord +{ + nsCString canonicalName; + NetAddrArray addrs; +}; + +union DNSRequestResponse +{ + DNSRecord; + nsresult; // if error +}; + + +} // namespace ipc +} // namespace mozilla diff --git a/netwerk/dns/moz.build b/netwerk/dns/moz.build index eb3ed2e490e..bec4e8aa8d2 100644 --- a/netwerk/dns/moz.build +++ b/netwerk/dns/moz.build @@ -16,7 +16,12 @@ XPIDL_SOURCES += [ XPIDL_MODULE = 'necko_dns' EXPORTS.mozilla.net += [ + 'ChildDNSService.h', 'DNS.h', + 'DNSListenerProxy.h', + 'DNSRequestChild.h', + 'DNSRequestParent.h', + 'PDNSParams.h', ] SOURCES += [ @@ -25,7 +30,11 @@ SOURCES += [ ] UNIFIED_SOURCES += [ + 'ChildDNSService.cpp', 'DNS.cpp', + 'DNSListenerProxy.cpp', + 'DNSRequestChild.cpp', + 'DNSRequestParent.cpp', 'nameprep.c', 'nsDNSService2.cpp', 'nsIDNService.cpp', @@ -33,10 +42,17 @@ UNIFIED_SOURCES += [ 'race.c', ] +IPDL_SOURCES = [ + 'PDNSRequest.ipdl', + 'PDNSRequestParams.ipdlh', +] + FAIL_ON_WARNINGS = True MSVC_ENABLE_PGO = True +include('/ipc/chromium/chromium-config.mozbuild') + FINAL_LIBRARY = 'necko' GENERATED_FILES = [ diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index f1094444a92..56d4be7d2f4 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -1,4 +1,5 @@ -/* vim:set ts=4 sw=4 sts=4 et cin: */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set sw=4 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/. */ @@ -33,6 +34,9 @@ #include "mozilla/Attributes.h" #include "mozilla/VisualEventTracer.h" +#include "mozilla/net/NeckoCommon.h" +#include "mozilla/net/ChildDNSService.h" +#include "mozilla/net/DNSListenerProxy.h" using namespace mozilla; using namespace mozilla::net; @@ -410,6 +414,43 @@ nsDNSService::~nsDNSService() NS_IMPL_ISUPPORTS_INHERITED3(nsDNSService, MemoryUniReporter, nsIDNSService, nsPIDNSService, nsIObserver) +/****************************************************************************** + * nsDNSService impl: + * singleton instance ctor/dtor methods + ******************************************************************************/ +static nsDNSService *gDNSService; + +nsIDNSService* +nsDNSService::GetXPCOMSingleton() +{ + if (IsNeckoChild()) { + return ChildDNSService::GetSingleton(); + } + + return GetSingleton(); +} + +nsDNSService* +nsDNSService::GetSingleton() +{ + NS_ASSERTION(!IsNeckoChild(), "not a parent process"); + + if (gDNSService) { + NS_ADDREF(gDNSService); + return gDNSService; + } + + gDNSService = new nsDNSService(); + if (gDNSService) { + NS_ADDREF(gDNSService); + if (NS_FAILED(gDNSService->Init())) { + NS_RELEASE(gDNSService); + } + } + + return gDNSService; +} + NS_IMETHODIMP nsDNSService::Init() { @@ -563,70 +604,6 @@ nsDNSService::SetPrefetchEnabled(bool inVal) return NS_OK; } -namespace { - -class DNSListenerProxy MOZ_FINAL : public nsIDNSListener -{ -public: - DNSListenerProxy(nsIDNSListener* aListener, nsIEventTarget* aTargetThread) - // Sometimes aListener is a main-thread only object like XPCWrappedJS, and - // sometimes it's a threadsafe object like nsSOCKSSocketInfo. Use a main- - // thread pointer holder, but disable strict enforcement of thread invariants. - // The AddRef implementation of XPCWrappedJS will assert if we go wrong here. - : mListener(new nsMainThreadPtrHolder(aListener, false)) - , mTargetThread(aTargetThread) - { } - - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIDNSLISTENER - - class OnLookupCompleteRunnable : public nsRunnable - { - public: - OnLookupCompleteRunnable(const nsMainThreadPtrHandle& aListener, - nsICancelable* aRequest, - nsIDNSRecord* aRecord, - nsresult aStatus) - : mListener(aListener) - , mRequest(aRequest) - , mRecord(aRecord) - , mStatus(aStatus) - { } - - NS_DECL_NSIRUNNABLE - - private: - nsMainThreadPtrHandle mListener; - nsCOMPtr mRequest; - nsCOMPtr mRecord; - nsresult mStatus; - }; - -private: - nsMainThreadPtrHandle mListener; - nsCOMPtr mTargetThread; -}; - -NS_IMPL_ISUPPORTS1(DNSListenerProxy, nsIDNSListener) - -NS_IMETHODIMP -DNSListenerProxy::OnLookupComplete(nsICancelable* aRequest, - nsIDNSRecord* aRecord, - nsresult aStatus) -{ - nsRefPtr r = - new OnLookupCompleteRunnable(mListener, aRequest, aRecord, aStatus); - return mTargetThread->Dispatch(r, NS_DISPATCH_NORMAL); -} - -NS_IMETHODIMP -DNSListenerProxy::OnLookupCompleteRunnable::Run() -{ - mListener->OnLookupComplete(mRequest, mRecord, mStatus); - return NS_OK; -} - -} // anonymous namespace NS_IMETHODIMP nsDNSService::AsyncResolve(const nsACString &hostname, @@ -670,6 +647,7 @@ nsDNSService::AsyncResolve(const nsACString &hostname, hostPtr = &hostACE; } + // make sure JS callers get notification on the main thread nsCOMPtr wrappedListener = do_QueryInterface(listener); if (wrappedListener && !target) { nsCOMPtr mainThread; diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h index 15c925205fc..99fd26ae9b1 100644 --- a/netwerk/dns/nsDNSService2.h +++ b/netwerk/dns/nsDNSService2.h @@ -1,3 +1,5 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set sw=4 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/. */ @@ -30,6 +32,8 @@ public: nsDNSService(); ~nsDNSService(); + static nsIDNSService* GetXPCOMSingleton(); + int64_t Amount() MOZ_OVERRIDE { return SizeOfIncludingThis(MallocSizeOf); @@ -37,6 +41,8 @@ public: size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; private: + static nsDNSService* GetSingleton(); + uint16_t GetAFForLookup(const nsACString &host, uint32_t flags); nsRefPtr mResolver; diff --git a/netwerk/dns/nsEffectiveTLDService.h b/netwerk/dns/nsEffectiveTLDService.h index a8e0104d984..a685a836845 100644 --- a/netwerk/dns/nsEffectiveTLDService.h +++ b/netwerk/dns/nsEffectiveTLDService.h @@ -3,6 +3,9 @@ * 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 EffectiveTLDService_h +#define EffectiveTLDService_h + #include "nsIEffectiveTLDService.h" #include "nsIMemoryReporter.h" @@ -124,3 +127,5 @@ private: nsTHashtable mHash; nsCOMPtr mIDNService; }; + +#endif // EffectiveTLDService_h diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index b73ff8d22ba..d6de2adb4e7 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -878,9 +878,9 @@ nsHostResolver::ConditionallyCreateThread(nsHostRecord *rec) #include "windns.h" #include "windows.h" -typedef DNS_STATUS (__stdcall * DnsQueryFunc) (PCTSTR lpstrName, WORD wType, +typedef DNS_STATUS (__stdcall * DnsQueryFunc) (LPCSTR lpstrName, WORD wType, DWORD Options, PVOID pExtra, - PDNS_RECORD *ppQueryResultsSet, + PDNS_RECORDA *ppQueryResultsSet, PVOID *pReserved); class ExperimentFinishedRunner : public nsRunnable @@ -1055,7 +1055,7 @@ public: } if (srvStatus == DNS_RCODE_NOERROR) { - DNS_SRV_DATA *srvData = &srvResults->Data.Srv; + DNS_SRV_DATAA *srvData = &srvResults->Data.Srv; if (_stricmp(srvData->pNameTarget, "success.http2test.mozilla.org") || srvData->wPort != 443 || srvData->wPriority != 100 || diff --git a/netwerk/ipc/NeckoChild.cpp b/netwerk/ipc/NeckoChild.cpp index f1c5b6debff..e3b993367a7 100644 --- a/netwerk/ipc/NeckoChild.cpp +++ b/netwerk/ipc/NeckoChild.cpp @@ -14,6 +14,7 @@ #include "mozilla/net/WyciwygChannelChild.h" #include "mozilla/net/FTPChannelChild.h" #include "mozilla/net/WebSocketChannelChild.h" +#include "mozilla/net/DNSRequestChild.h" #include "mozilla/net/RemoteOpenFileChild.h" #include "mozilla/dom/network/TCPSocketChild.h" #include "mozilla/dom/network/TCPServerSocketChild.h" @@ -230,6 +231,24 @@ NeckoChild::DeallocPUDPSocketChild(PUDPSocketChild* child) return true; } +PDNSRequestChild* +NeckoChild::AllocPDNSRequestChild(const nsCString& aHost, + const uint32_t& aFlags) +{ + // 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; +} + +bool +NeckoChild::DeallocPDNSRequestChild(PDNSRequestChild* aChild) +{ + DNSRequestChild *p = static_cast(aChild); + p->ReleaseIPDLReference(); + return true; +} + PRemoteOpenFileChild* NeckoChild::AllocPRemoteOpenFileChild(const URIParams&, const OptionalURIParams&) { diff --git a/netwerk/ipc/NeckoChild.h b/netwerk/ipc/NeckoChild.h index c21646c8270..8cacf36614a 100644 --- a/netwerk/ipc/NeckoChild.h +++ b/netwerk/ipc/NeckoChild.h @@ -51,6 +51,9 @@ protected: const uint16_t& aPort, const nsCString& aFilter); virtual bool DeallocPUDPSocketChild(PUDPSocketChild*); + virtual PDNSRequestChild* AllocPDNSRequestChild(const nsCString& aHost, + const uint32_t& aFlags); + virtual bool DeallocPDNSRequestChild(PDNSRequestChild*); virtual PRemoteOpenFileChild* AllocPRemoteOpenFileChild(const URIParams&, const OptionalURIParams&); virtual bool DeallocPRemoteOpenFileChild(PRemoteOpenFileChild*); diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp index 77026520886..a2cd6e57c20 100644 --- a/netwerk/ipc/NeckoParent.cpp +++ b/netwerk/ipc/NeckoParent.cpp @@ -16,6 +16,7 @@ #ifdef NECKO_PROTOCOL_rtsp #include "mozilla/net/RtspControllerParent.h" #endif +#include "mozilla/net/DNSRequestParent.h" #include "mozilla/net/RemoteOpenFileParent.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/TabParent.h" @@ -428,6 +429,32 @@ NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor) return true; } +PDNSRequestParent* +NeckoParent::AllocPDNSRequestParent(const nsCString& aHost, + const uint32_t& aFlags) +{ + DNSRequestParent *p = new DNSRequestParent(); + p->AddRef(); + return p; +} + +bool +NeckoParent::RecvPDNSRequestConstructor(PDNSRequestParent* aActor, + const nsCString& aHost, + const uint32_t& aFlags) +{ + static_cast(aActor)->DoAsyncResolve(aHost, aFlags); + return true; +} + +bool +NeckoParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent) +{ + DNSRequestParent *p = static_cast(aParent); + p->Release(); + return true; +} + PRemoteOpenFileParent* NeckoParent::AllocPRemoteOpenFileParent(const URIParams& aURI, const OptionalURIParams& aAppURI) diff --git a/netwerk/ipc/NeckoParent.h b/netwerk/ipc/NeckoParent.h index 09084f7ba5a..35d51c22c08 100644 --- a/netwerk/ipc/NeckoParent.h +++ b/netwerk/ipc/NeckoParent.h @@ -124,6 +124,12 @@ protected: const uint16_t& aPort, const nsCString& aFilter); virtual bool DeallocPUDPSocketParent(PUDPSocketParent*); + virtual PDNSRequestParent* AllocPDNSRequestParent(const nsCString& aHost, + const uint32_t& aFlags); + virtual bool RecvPDNSRequestConstructor(PDNSRequestParent* actor, + const nsCString& hostName, + const uint32_t& flags); + virtual bool DeallocPDNSRequestParent(PDNSRequestParent*); virtual bool RecvHTMLDNSPrefetch(const nsString& hostname, const uint16_t& flags); virtual bool RecvCancelHTMLDNSPrefetch(const nsString& hostname, diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl index c33a6f30d3b..fe2c984e600 100644 --- a/netwerk/ipc/PNecko.ipdl +++ b/netwerk/ipc/PNecko.ipdl @@ -16,6 +16,7 @@ include protocol PTCPSocket; include protocol PTCPServerSocket; include protocol PUDPSocket; include protocol PRemoteOpenFile; +include protocol PDNSRequest; include protocol PBlob; //FIXME: bug #792908 include protocol PRtspController; @@ -41,6 +42,7 @@ sync protocol PNecko manages PTCPSocket; manages PTCPServerSocket; manages PUDPSocket; + manages PDNSRequest; manages PRemoteOpenFile; manages PRtspController; @@ -59,6 +61,8 @@ parent: PTCPServerSocket(uint16_t localPort, uint16_t backlog, nsString binaryType); PUDPSocket(nsCString host, uint16_t port, nsCString filter); + PDNSRequest(nsCString hostName, uint32_t flags); + PRemoteOpenFile(URIParams fileuri, OptionalURIParams appuri); HTMLDNSPrefetch(nsString hostname, uint16_t flags); diff --git a/netwerk/test/unit_ipc/test_dns_service_wrap.js b/netwerk/test/unit_ipc/test_dns_service_wrap.js new file mode 100644 index 00000000000..fdbecf16d31 --- /dev/null +++ b/netwerk/test/unit_ipc/test_dns_service_wrap.js @@ -0,0 +1,7 @@ +// +// Run test script in content process instead of chrome (xpcshell's default) +// + +function run_test() { + run_test_in_child("../unit/test_dns_service.js"); +} diff --git a/netwerk/test/unit_ipc/xpcshell.ini b/netwerk/test/unit_ipc/xpcshell.ini index 46a28dff015..9c9691f6ca2 100644 --- a/netwerk/test/unit_ipc/xpcshell.ini +++ b/netwerk/test/unit_ipc/xpcshell.ini @@ -9,6 +9,7 @@ support-files = disabled_test_bug528292_wrap.js [test_channel_close_wrap.js] [test_cookie_header_wrap.js] [test_cookiejars_wrap.js] +[test_dns_service_wrap.js] [test_duplicate_headers_wrap.js] [test_event_sink_wrap.js] [test_head_wrap.js]