Bug 1450893 - Add way to clear DNS cache r=dragana a=pascalc
authorValentin Gosu <valentin.gosu@gmail.com>
Thu, 21 Mar 2019 12:41:39 +0000
changeset 516400 1805599da5fdba43397ce786ce54ff2c15a33156
parent 516399 b63e6642e034cc0af0fba29f58a8572cbca53963
child 516401 41f52aefb0c705da448129dfa84e1f4e6ac8699a
push id1986
push userarchaeopteryx@coole-files.de
push dateMon, 25 Mar 2019 15:47:39 +0000
treeherdermozilla-release@4e09989843e2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana, pascalc
bugs1450893
milestone66.0.2
Bug 1450893 - Add way to clear DNS cache r=dragana a=pascalc Differential Revision: https://phabricator.services.mozilla.com/D24300
netwerk/dns/ChildDNSService.cpp
netwerk/dns/nsDNSService2.cpp
netwerk/dns/nsHostResolver.cpp
netwerk/dns/nsHostResolver.h
netwerk/dns/nsIDNSService.idl
--- a/netwerk/dns/ChildDNSService.cpp
+++ b/netwerk/dns/ChildDNSService.cpp
@@ -281,16 +281,19 @@ ChildDNSService::GetDNSCacheEntries(
     nsTArray<mozilla::net::DNSCacheEntries> *args) {
   // Only used by networking dashboard, so may not ever need this in child.
   // (and would provide a way to spy on what hosts other apps are connecting to,
   // unless we start keeping per-app DNS caches).
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
+ChildDNSService::ClearCache(bool aTrrToo) { return NS_ERROR_NOT_AVAILABLE; }
+
+NS_IMETHODIMP
 ChildDNSService::GetMyHostName(nsACString &result) {
   // TODO: get value from parent during PNecko construction?
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 void ChildDNSService::NotifyRequestDone(DNSRequestChild *aDnsRequest) {
   // We need the original flags and listener for the pending requests hash.
   uint32_t originalFlags = aDnsRequest->mFlags & ~RESOLVE_OFFLINE;
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -1126,17 +1126,17 @@ nsDNSService::Observe(nsISupports *subje
       mResolver->SetCacheLimits(mResCacheEntries, mResCacheExpiration,
                                 mResCacheGrace);
     }
   } else if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
     Shutdown();
   }
 
   if (flushCache) {
-    mResolver->FlushCache();
+    mResolver->FlushCache(false);
     return NS_OK;
   }
 
   return NS_OK;
 }
 
 uint16_t nsDNSService::GetAFForLookup(const nsACString &host, uint32_t flags) {
   if (mDisableIPv6 || (flags & RESOLVE_DISABLE_IPV6)) return PR_AF_INET;
@@ -1193,16 +1193,22 @@ uint16_t nsDNSService::GetAFForLookup(co
 NS_IMETHODIMP
 nsDNSService::GetDNSCacheEntries(
     nsTArray<mozilla::net::DNSCacheEntries> *args) {
   NS_ENSURE_TRUE(mResolver, NS_ERROR_NOT_INITIALIZED);
   mResolver->GetDNSCacheEntries(args);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDNSService::ClearCache(bool aTrrToo) {
+  mResolver->FlushCache(aTrrToo);
+  return NS_OK;
+}
+
 size_t nsDNSService::SizeOfIncludingThis(
     mozilla::MallocSizeOf mallocSizeOf) const {
   // Measurement of the following members may be added later if DMD finds it
   // is worthwhile:
   // - mIDN
   // - mLock
 
   size_t n = mallocSizeOf(this);
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -381,20 +381,20 @@ void AddrHostRecord::Cancel() {
   if (mTrrAAAA) {
     mTrrAAAA->Cancel();
     mTrrAAAA = nullptr;
   }
 }
 
 // Returns true if the entry can be removed, or false if it should be left.
 // Sets mResolveAgain true for entries being resolved right now.
-bool AddrHostRecord::RemoveOrRefresh() {
+bool AddrHostRecord::RemoveOrRefresh(bool aTrrToo) {
   // no need to flush TRRed names, they're not resolved "locally"
   MutexAutoLock lock(addr_info_lock);
-  if (addr_info && addr_info->IsTRR()) {
+  if (addr_info && !aTrrToo && addr_info->IsTRR()) {
     return false;
   }
   if (mNative) {
     if (!onQueue) {
       // The request has been passed to the OS resolver. The resultant DNS
       // record should be considered stale and not trusted; set a flag to
       // ensure it is called again.
       mResolveAgain = true;
@@ -711,17 +711,17 @@ void nsHostResolver::ClearPendingQueue(
 // trust names that were resolved before this change. They may resolve
 // differently now.
 //
 // This function removes all existing resolved host entries from the hash.
 // Names that are in the pending queues can be left there. Entries in the
 // cache that have 'Resolve' set true but not 'onQueue' are being resolved
 // right now, so we need to mark them to get re-resolved on completion!
 
-void nsHostResolver::FlushCache() {
+void nsHostResolver::FlushCache(bool aTrrToo) {
   MutexAutoLock lock(mLock);
   mEvictionQSize = 0;
 
   // Clear the evictionQ and remove all its corresponding entries from
   // the cache first
   if (!mEvictionQ.isEmpty()) {
     for (RefPtr<nsHostRecord> rec : mEvictionQ) {
       rec->Cancel();
@@ -734,17 +734,17 @@ void nsHostResolver::FlushCache() {
   for (auto iter = mRecordDB.Iter(); !iter.Done(); iter.Next()) {
     nsHostRecord *record = iter.UserData();
     // Try to remove the record, or mark it for refresh.
     // By-type records are from TRR. We do not need to flush those entry
     // when the network has change, because they are not local.
     if (record->IsAddrRecord()) {
       RefPtr<AddrHostRecord> addrRec = do_QueryObject(record);
       MOZ_ASSERT(addrRec);
-      if (addrRec->RemoveOrRefresh()) {
+      if (addrRec->RemoveOrRefresh(aTrrToo)) {
         if (record->isInList()) {
           record->remove();
         }
         iter.Remove();
       }
     }
   }
 }
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -199,18 +199,18 @@ class AddrHostRecord final : public nsHo
   explicit AddrHostRecord(const nsHostKey &key);
   ~AddrHostRecord();
 
   // Checks if the record is usable (not expired and has a value)
   bool HasUsableResultInternal() const override;
 
   void Cancel() override;
 
-  bool RemoveOrRefresh();  // Mark records currently being resolved as needed
-                           // to resolve again.
+  bool RemoveOrRefresh(bool aTrrToo);  // Mark records currently being resolved
+                                       // as needed to resolve again.
 
   void ResolveComplete();
 
   enum DnsPriority {
     DNS_PRIORITY_LOW,
     DNS_PRIORITY_MEDIUM,
     DNS_PRIORITY_HIGH,
   };
@@ -470,17 +470,17 @@ class nsHostResolver : public nsISupport
     RES_REFRESH_CACHE = nsIDNSService::RESOLVE_REFRESH_CACHE
   };
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
   /**
    * Flush the DNS cache.
    */
-  void FlushCache();
+  void FlushCache(bool aTrrToo);
 
   LookupStatus CompleteLookup(nsHostRecord *, nsresult,
                               mozilla::net::AddrInfo *, bool pb,
                               const nsACString &aOriginsuffix) override;
   LookupStatus CompleteLookupByType(nsHostRecord *, nsresult,
                                     const nsTArray<nsCString> *aResult,
                                     uint32_t aTtl, bool pb) override;
   nsresult GetHostRecord(const nsACString &host, uint16_t type, uint16_t flags,
--- a/netwerk/dns/nsIDNSService.idl
+++ b/netwerk/dns/nsIDNSService.idl
@@ -207,16 +207,27 @@ interface nsIDNSService : nsISupports
 
     /**
      * The method takes a pointer to an nsTArray
      * and fills it with cache entry data
      * Called by the networking dashboard
      */
     [noscript] void getDNSCacheEntries(in EntriesArray args);
 
+
+    /**
+     * Clears the DNS cache.
+     * @param aTrrToo
+     *        If true we will clear TRR cached entries too. Since these
+     *        are resolved remotely it's not necessary to clear them when
+     *        the network status changes, but it's sometimes useful to do so
+     *        for tests or other situations.
+     */
+    void clearCache(in boolean aTrrToo);
+
     /**
      * @return the hostname of the operating system.
      */
     readonly attribute AUTF8String myHostName;
 
     /*************************************************************************
      * Listed below are the various flags that may be OR'd together to form
      * the aFlags parameter passed to asyncResolve() and resolve().