From db05cbea1d95afa714892cb95ec6b5d4d0b973bc Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Fri, 19 Jul 2013 18:40:00 -0400 Subject: [PATCH] bug 887753 - server not found after reconnecting to etherpad r=sworkman --- netwerk/dns/nsHostResolver.cpp | 57 ++++++++++++++++++++++------------ netwerk/dns/nsHostResolver.h | 3 +- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index b8504d3a5c01..9671c38acbaa 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -131,6 +131,26 @@ private: //---------------------------------------------------------------------------- +static inline bool +IsHighPriority(uint16_t flags) +{ + return !(flags & (nsHostResolver::RES_PRIORITY_LOW | nsHostResolver::RES_PRIORITY_MEDIUM)); +} + +static inline bool +IsMediumPriority(uint16_t flags) +{ + return flags & nsHostResolver::RES_PRIORITY_MEDIUM; +} + +static inline bool +IsLowPriority(uint16_t flags) +{ + return flags & nsHostResolver::RES_PRIORITY_LOW; +} + +//---------------------------------------------------------------------------- + // this macro filters out any flags that are not used when constructing the // host key. the significant flags are those that would affect the resulting // host record (i.e., the flags that are passed down to PR_GetAddrInfoByName). @@ -145,6 +165,7 @@ nsHostRecord::nsHostRecord(const nsHostKey *key) , resolving(false) , onQueue(false) , usingAnyThread(false) + , mDoomed(false) { host = ((char *) this) + sizeof(nsHostRecord); memcpy((char *) host, key->host, strlen(key->host) + 1); @@ -213,6 +234,9 @@ nsHostRecord::ReportUnusable(NetAddr *aAddress) // must call locked LOG(("Adding address to blacklist for host [%s], host record [%p].\n", host, this)); + if (negative) + mDoomed = true; + char buf[kIPv6CStrBufSize]; if (NetAddrToString(aAddress, buf, sizeof(buf))) { LOG(("Successfully adding address [%s] to blacklist for host [%s].\n", buf, host)); @@ -228,6 +252,19 @@ nsHostRecord::ResetBlacklist() mBlacklistedItems.Clear(); } +bool +nsHostRecord::HasUsableResult(uint16_t queryFlags) const +{ + if (mDoomed) + return false; + + // don't use cached negative results for high priority queries. + if (negative && IsHighPriority(queryFlags)) + return false; + + return addr_info || addr || negative; +} + //---------------------------------------------------------------------------- struct nsHostDBEnt : PLDHashEntryHdr @@ -463,24 +500,6 @@ nsHostResolver::Shutdown() #endif } -static inline bool -IsHighPriority(uint16_t flags) -{ - return !(flags & (nsHostResolver::RES_PRIORITY_LOW | nsHostResolver::RES_PRIORITY_MEDIUM)); -} - -static inline bool -IsMediumPriority(uint16_t flags) -{ - return flags & nsHostResolver::RES_PRIORITY_MEDIUM; -} - -static inline bool -IsLowPriority(uint16_t flags) -{ - return flags & nsHostResolver::RES_PRIORITY_LOW; -} - void nsHostResolver::MoveQueue(nsHostRecord *aRec, PRCList &aDestQ) { @@ -537,7 +556,7 @@ nsHostResolver::ResolveHost(const char *host, rv = NS_ERROR_OUT_OF_MEMORY; // do we have a cached result that we can reuse? else if (!(flags & RES_BYPASS_CACHE) && - he->rec->HasResult() && + he->rec->HasUsableResult(flags) && TimeStamp::NowLoRes() <= (he->rec->expiration + TimeDuration::FromSeconds(mGracePeriod * 60))) { LOG(("Using cached record for host [%s].\n", host)); // put reference to host record on stack... diff --git a/netwerk/dns/nsHostResolver.h b/netwerk/dns/nsHostResolver.h index 8cce0c7a675a..ce0b488705e4 100644 --- a/netwerk/dns/nsHostResolver.h +++ b/netwerk/dns/nsHostResolver.h @@ -80,7 +80,7 @@ public: mozilla::TimeStamp expiration; - bool HasResult() const { return addr_info || addr || negative; } + bool HasUsableResult(uint16_t queryFlags) const; // hold addr_info_lock when calling the blacklist functions bool Blacklisted(mozilla::net::NetAddr *query); @@ -98,6 +98,7 @@ private: bool onQueue; /* true if pending and on the queue (not yet given to getaddrinfo())*/ bool usingAnyThread; /* true if off queue and contributing to mActiveAnyThreadCount */ + bool mDoomed; /* explicitly expired */ // a list of addresses associated with this record that have been reported // as unusable. the list is kept as a set of strings to make it independent