netwerk/dns/ChildDNSService.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "mozilla/net/ChildDNSService.h"
     6 #include "nsIDNSListener.h"
     7 #include "nsNetUtil.h"
     8 #include "nsIThread.h"
     9 #include "nsThreadUtils.h"
    10 #include "nsIXPConnect.h"
    11 #include "nsIPrefService.h"
    12 #include "nsIProtocolProxyService.h"
    13 #include "mozilla/net/NeckoChild.h"
    14 #include "mozilla/net/DNSRequestChild.h"
    15 #include "mozilla/net/DNSListenerProxy.h"
    17 namespace mozilla {
    18 namespace net {
    20 //-----------------------------------------------------------------------------
    21 // ChildDNSService
    22 //-----------------------------------------------------------------------------
    24 static ChildDNSService *gChildDNSService;
    25 static const char kPrefNameDisablePrefetch[] = "network.dns.disablePrefetch";
    27 ChildDNSService* ChildDNSService::GetSingleton()
    28 {
    29   MOZ_ASSERT(IsNeckoChild());
    31   if (!gChildDNSService) {
    32     gChildDNSService = new ChildDNSService();
    33   }
    35   NS_ADDREF(gChildDNSService);
    36   return gChildDNSService;
    37 }
    39 NS_IMPL_ISUPPORTS(ChildDNSService,
    40                   nsIDNSService,
    41                   nsPIDNSService,
    42                   nsIObserver)
    44 ChildDNSService::ChildDNSService()
    45   : mFirstTime(true)
    46   , mOffline(false)
    47 {
    48   MOZ_ASSERT(IsNeckoChild());
    49 }
    51 ChildDNSService::~ChildDNSService()
    52 {
    54 }
    56 //-----------------------------------------------------------------------------
    57 // ChildDNSService::nsIDNSService
    58 //-----------------------------------------------------------------------------
    60 NS_IMETHODIMP
    61 ChildDNSService::AsyncResolve(const nsACString  &hostname,
    62                               uint32_t           flags,
    63                               nsIDNSListener    *listener,
    64                               nsIEventTarget    *target_,
    65                               nsICancelable    **result)
    66 {
    67   NS_ENSURE_TRUE(gNeckoChild != nullptr, NS_ERROR_FAILURE);
    69   if (mDisablePrefetch && (flags & RESOLVE_SPECULATE)) {
    70     return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
    71   }
    73   // Support apps being 'offline' even if parent is not: avoids DNS traffic by
    74   // apps that have been told they are offline.
    75   if (mOffline) {
    76     flags |= RESOLVE_OFFLINE;
    77   }
    79   // make sure JS callers get notification on the main thread
    80   nsCOMPtr<nsIEventTarget> target = target_;
    81   nsCOMPtr<nsIXPConnectWrappedJS> wrappedListener = do_QueryInterface(listener);
    82   if (wrappedListener && !target) {
    83     nsCOMPtr<nsIThread> mainThread;
    84     NS_GetMainThread(getter_AddRefs(mainThread));
    85     target = do_QueryInterface(mainThread);
    86   }
    87   if (target) {
    88     // Guarantee listener freed on main thread.  Not sure we need this in child
    89     // (or in parent in nsDNSService.cpp) but doesn't hurt.
    90     listener = new DNSListenerProxy(listener, target);
    91   }
    93   nsRefPtr<DNSRequestChild> childReq =
    94     new DNSRequestChild(nsCString(hostname), flags, listener, target);
    96   childReq->StartRequest();
    98   childReq.forget(result);
    99   return NS_OK;
   100 }
   102 NS_IMETHODIMP
   103 ChildDNSService::CancelAsyncResolve(const nsACString  &aHostname,
   104                                     uint32_t           aFlags,
   105                                     nsIDNSListener    *aListener,
   106                                     nsresult           aReason)
   107 {
   108   if (mDisablePrefetch && (aFlags & RESOLVE_SPECULATE)) {
   109     return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
   110   }
   112   // TODO: keep a hashtable of pending requests, so we can obey cancel semantics
   113   // (call OnLookupComplete with aReason).  Also possible we could send IPDL to
   114   // parent to cancel.
   115   return NS_ERROR_NOT_AVAILABLE;
   116 }
   118 NS_IMETHODIMP
   119 ChildDNSService::Resolve(const nsACString &hostname,
   120                          uint32_t          flags,
   121                          nsIDNSRecord    **result)
   122 {
   123   // not planning to ever support this, since sync IPDL is evil.
   124   return NS_ERROR_NOT_AVAILABLE;
   125 }
   127 NS_IMETHODIMP
   128 ChildDNSService::GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries> *args)
   129 {
   130   // Only used by networking dashboard, so may not ever need this in child.
   131   // (and would provide a way to spy on what hosts other apps are connecting to,
   132   // unless we start keeping per-app DNS caches).
   133   return NS_ERROR_NOT_AVAILABLE;
   134 }
   136 NS_IMETHODIMP
   137 ChildDNSService::GetMyHostName(nsACString &result)
   138 {
   139   // TODO: get value from parent during PNecko construction?
   140   return NS_ERROR_NOT_AVAILABLE;
   141 }
   143 //-----------------------------------------------------------------------------
   144 // ChildDNSService::nsPIDNSService
   145 //-----------------------------------------------------------------------------
   147 nsresult
   148 ChildDNSService::Init()
   149 {
   150   // Disable prefetching either by explicit preference or if a manual proxy
   151   // is configured
   152   bool disablePrefetch = false;
   153   int  proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
   155   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   156   prefs->GetBoolPref(kPrefNameDisablePrefetch, &disablePrefetch);
   157   if (prefs) {
   158     prefs->GetIntPref("network.proxy.type", &proxyType);
   159     prefs->GetBoolPref(kPrefNameDisablePrefetch, &disablePrefetch);
   160   }
   162   if (mFirstTime) {
   163     mFirstTime = false;
   164     if (prefs) {
   165       prefs->AddObserver(kPrefNameDisablePrefetch, this, false);
   167       // Monitor these to see if there is a change in proxy configuration
   168       // If a manual proxy is in use, disable prefetch implicitly
   169       prefs->AddObserver("network.proxy.type", this, false);
   170     }
   171   }
   173   mDisablePrefetch = disablePrefetch ||
   174                      (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
   176   return NS_OK;
   177 }
   179 nsresult
   180 ChildDNSService::Shutdown()
   181 {
   182   return NS_OK;
   183 }
   185 NS_IMETHODIMP
   186 ChildDNSService::GetPrefetchEnabled(bool *outVal)
   187 {
   188   *outVal = !mDisablePrefetch;
   189   return NS_OK;
   190 }
   192 NS_IMETHODIMP
   193 ChildDNSService::SetPrefetchEnabled(bool inVal)
   194 {
   195   mDisablePrefetch = !inVal;
   196   return NS_OK;
   197 }
   199 NS_IMETHODIMP
   200 ChildDNSService::GetOffline(bool* aResult)
   201 {
   202   *aResult = mOffline;
   203   return NS_OK;
   204 }
   206 NS_IMETHODIMP
   207 ChildDNSService::SetOffline(bool value)
   208 {
   209   mOffline = value;
   210   return NS_OK;
   211 }
   213 //-----------------------------------------------------------------------------
   214 // ChildDNSService::nsIObserver
   215 //-----------------------------------------------------------------------------
   217 NS_IMETHODIMP
   218 ChildDNSService::Observe(nsISupports *subject, const char *topic,
   219                          const char16_t *data)
   220 {
   221   // we are only getting called if a preference has changed.
   222   NS_ASSERTION(strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0,
   223                "unexpected observe call");
   225   // Reread prefs
   226   Init();
   227   return NS_OK;
   228 }
   230 } // namespace net
   231 } // namespace mozilla

mercurial