Bug 1123324 - Additional fix for nsHostResolver. r=sworkman
authorDragana Damjanovic <dd.mozilla@gmail.com>
Tue, 10 Feb 2015 08:45:00 -0500
changeset 228765 e8e048191f8b4abe0e748378821543e040956bc1
parent 228764 db6c43f3ce1b4aaa95095faec2dae330da2d95da
child 228766 73ff82f8207e7eb8a3ce8867fa2c056c22e21c3f
push idunknown
push userunknown
push dateunknown
reviewerssworkman
bugs1123324
milestone38.0a1
Bug 1123324 - Additional fix for nsHostResolver. r=sworkman
netwerk/dns/nsHostResolver.cpp
netwerk/dns/nsHostResolver.h
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -205,21 +205,24 @@ void
 nsHostRecord::SetExpiration(const mozilla::TimeStamp& now, unsigned int valid, unsigned int grace)
 {
     mValidStart = now;
     mGraceStart = now + TimeDuration::FromSeconds(valid);
     mValidEnd = now + TimeDuration::FromSeconds(valid + grace);
 }
 
 void
-nsHostRecord::CopyExpirationTimesFrom(const nsHostRecord *aFromHostRecord)
+nsHostRecord::CopyExpirationTimesAndFlagsFrom(const nsHostRecord *aFromHostRecord)
 {
+    // This is used to copy information from a cache entry to a record. All
+    // information necessary for HasUsableRecord needs to be copied.
     mValidStart = aFromHostRecord->mValidStart;
     mValidEnd = aFromHostRecord->mValidEnd;
     mGraceStart = aFromHostRecord->mGraceStart;
+    mDoomed = aFromHostRecord->mDoomed;
 }
 
 nsHostRecord::~nsHostRecord()
 {
     Telemetry::Accumulate(Telemetry::DNS_BLACKLIST_COUNT, mBlacklistedCount);
     delete addr_info;
     delete addr;
 }
@@ -834,52 +837,57 @@ nsHostResolver::ResolveHost(const char  
                     ((af == PR_AF_INET) || (af == PR_AF_INET6))) {
                     // First, search for an entry with AF_UNSPEC
                     const nsHostKey unspecKey = { host, flags, PR_AF_UNSPEC };
                     nsHostDBEnt *unspecHe = static_cast<nsHostDBEnt *>
                         (PL_DHashTableSearch(&mDB, &unspecKey));
                     NS_ASSERTION(!unspecHe ||
                                  (unspecHe && unspecHe->rec),
                                 "Valid host entries should contain a record");
+                    TimeStamp now = TimeStamp::NowLoRes();
                     if (unspecHe &&
-                        unspecHe->rec->HasUsableResult(TimeStamp::NowLoRes(), flags)) {
+                        unspecHe->rec->HasUsableResult(now, flags)) {
 
                         MOZ_ASSERT(unspecHe->rec->addr_info || unspecHe->rec->negative,
                                    "Entry should be resolved or negative.");
 
                         LOG(("  Trying AF_UNSPEC entry for [%s] af: %s.\n",
                             host, (af == PR_AF_INET) ? "AF_INET" : "AF_INET6"));
 
                         he->rec->addr_info = nullptr;
                         if (unspecHe->rec->negative) {
                             he->rec->negative = unspecHe->rec->negative;
-                            he->rec->CopyExpirationTimesFrom(unspecHe->rec);
+                            he->rec->CopyExpirationTimesAndFlagsFrom(unspecHe->rec);
                         } else if (unspecHe->rec->addr_info) {
                             // Search for any valid address in the AF_UNSPEC entry
                             // in the cache (not blacklisted and from the right
                             // family).
                             NetAddrElement *addrIter =
                                 unspecHe->rec->addr_info->mAddresses.getFirst();
                             while (addrIter) {
                                 if ((af == addrIter->mAddress.inet.family) &&
                                      !unspecHe->rec->Blacklisted(&addrIter->mAddress)) {
                                     if (!he->rec->addr_info) {
                                         he->rec->addr_info = new AddrInfo(
                                             unspecHe->rec->addr_info->mHostName,
                                             unspecHe->rec->addr_info->mCanonicalName);
-                                        he->rec->CopyExpirationTimesFrom(unspecHe->rec);
+                                        he->rec->CopyExpirationTimesAndFlagsFrom(unspecHe->rec);
                                     }
                                     he->rec->addr_info->AddAddress(
                                         new NetAddrElement(*addrIter));
                                 }
                                 addrIter = addrIter->getNext();
                             }
                         }
-                        if (he->rec->HasUsableResult(TimeStamp::NowLoRes(), flags)) {
+                        // Now check if we have a new record.
+                        if (he->rec->HasUsableResult(now, flags)) {
                             result = he->rec;
+                            if (he->rec->negative) {
+                                status = NS_ERROR_UNKNOWN_HOST;
+                            }
                             Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
                                                   METHOD_HIT);
                             ConditionallyRefreshRecord(he->rec, host);
                         }
                         // For AF_INET6, a new lookup means another AF_UNSPEC
                         // lookup. We have already iterated through the
                         // AF_UNSPEC addresses, so we mark this record as
                         // negative.
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -96,17 +96,17 @@ public:
     // If a record is in its grace period (and not expired), it will be used
     // but a request to refresh it will be made.
     mozilla::TimeStamp mGraceStart;
 
     // Convenience function for setting the timestamps above (mValidStart,
     // mValidEnd, and mGraceStart). valid and grace are durations in seconds.
     void SetExpiration(const mozilla::TimeStamp& now, unsigned int valid,
                        unsigned int grace);
-    void CopyExpirationTimesFrom(const nsHostRecord *aFromHostRecord);
+    void CopyExpirationTimesAndFlagsFrom(const nsHostRecord *aFromHostRecord);
 
     // Checks if the record is usable (not expired and has a value)
     bool HasUsableResult(const mozilla::TimeStamp& now, uint16_t queryFlags = 0) const;
 
     // hold addr_info_lock when calling the blacklist functions
     bool   Blacklisted(mozilla::net::NetAddr *query);
     void   ResetBlacklist();
     void   ReportUnusable(mozilla::net::NetAddr *addr);