Backed out changeset 89d06d103c10 (bug 939318) for Valgrind failures; CLOSED TREE
authorEd Morley <emorley@mozilla.com>
Wed, 24 Sep 2014 16:17:57 +0100
changeset 207059 c9d5d07e1a63bd9d83ccafe28d9c661ae41bbf1d
parent 207058 12fcec7a372cad443bf28d3f7206a235586d653e
child 207060 4f72287c59caee404fd91b64d08306a85a228ccf
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs939318
milestone35.0a1
backs out89d06d103c107dfa032af6cab9a7bf29a2b60907
Backed out changeset 89d06d103c10 (bug 939318) for Valgrind failures; CLOSED TREE
netwerk/base/public/nsINetworkLinkService.idl
netwerk/base/src/nsIOService.cpp
netwerk/base/src/nsIOService.h
netwerk/dns/nsDNSService2.cpp
netwerk/dns/nsHostResolver.cpp
netwerk/dns/nsHostResolver.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/system/win32/nsNotifyAddrListener.cpp
netwerk/system/win32/nsNotifyAddrListener.h
--- a/netwerk/base/public/nsINetworkLinkService.idl
+++ b/netwerk/base/public/nsINetworkLinkService.idl
@@ -5,17 +5,17 @@
  * 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 "nsISupports.idl"
 
 /**
  * Network link status monitoring service.
  */
-[scriptable, uuid(a8770c10-2f54-11e4-8c21-0800200c9a66)]
+[scriptable, uuid(f7d3be87-7403-4a1e-b89f-2797776e9b08)]
 interface nsINetworkLinkService : nsISupports
 {
   /* Link type constants */
   const unsigned long LINK_TYPE_UNKNOWN = 0;
   const unsigned long LINK_TYPE_ETHERNET = 1;
   const unsigned long LINK_TYPE_USB = 2;
   const unsigned long LINK_TYPE_WIFI = 3;
   const unsigned long LINK_TYPE_WIMAX = 4;
@@ -60,21 +60,16 @@ interface nsINetworkLinkService : nsISup
  * isLinkUp is now true, linkStatusKnown is true.
  */
 #define NS_NETWORK_LINK_DATA_UP      "up"
 /**
  * isLinkUp is now false, linkStatusKnown is true.
  */
 #define NS_NETWORK_LINK_DATA_DOWN    "down"
 /**
- * isLinkUp is still true, but the network setup is modified.
- * linkStatusKnown is true.
- */
-#define NS_NETWORK_LINK_DATA_CHANGED "changed"
-/**
  * linkStatusKnown is now false.
  */
 #define NS_NETWORK_LINK_DATA_UNKNOWN "unknown"
 
 /**
  * We send notifications through nsIObserverService with topic
  * NS_NETWORK_LINK_TYPE_TOPIC whenever the network connection type
  * changes. We pass one of the valid connection type constants
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -55,18 +55,18 @@ using namespace mozilla;
 #define NECKO_BUFFER_CACHE_COUNT_PREF "network.buffer.cache.count"
 #define NECKO_BUFFER_CACHE_SIZE_PREF  "network.buffer.cache.size"
 
 #define MAX_RECURSION_COUNT 50
 
 nsIOService* gIOService = nullptr;
 static bool gHasWarnedUploadChannel2;
 
-// A general port blacklist.  Connections to these ports will not be allowed
-// unless the protocol overrides.
+// A general port blacklist.  Connections to these ports will not be allowed unless 
+// the protocol overrides.
 //
 // TODO: I am sure that there are more ports to be added.  
 //       This cut is based on the classic mozilla codebase
 
 int16_t gBadPortList[] = { 
   1,    // tcpmux          
   7,    // echo     
   9,    // discard          
@@ -260,19 +260,20 @@ nsIOService::InitializeNetworkLinkServic
     if (mNetworkLinkService) {
         mNetworkLinkServiceInitialized = true;
     }
     else {
         // We can't really determine if the machine has a usable network connection,
         // so let's cross our fingers!
         mManageOfflineStatus = false;
     }
+   
 
     if (mManageOfflineStatus)
-        OnNetworkLinkEvent(NS_NETWORK_LINK_DATA_UNKNOWN);
+        TrackNetworkLinkStatusForOffline();
     else
         SetOffline(false);
     
     return rv;
 }
 
 nsIOService*
 nsIOService::GetInstance() {
@@ -916,17 +917,17 @@ nsIOService::Observe(nsISupports *subjec
             mOfflineForProfileChange = true;
             SetOffline(true);
         }
     }
     else if (!strcmp(topic, kProfileChangeNetRestoreTopic)) {
         if (mOfflineForProfileChange) {
             mOfflineForProfileChange = false;
             if (!mManageOfflineStatus ||
-                NS_FAILED(OnNetworkLinkEvent(NS_NETWORK_LINK_DATA_UNKNOWN))) {
+                NS_FAILED(TrackNetworkLinkStatusForOffline())) {
                 SetOffline(false);
             }
         } 
     } 
     else if (!strcmp(topic, kProfileDoChange)) { 
         if (data && NS_LITERAL_STRING("startup").Equals(data)) {
             // Lazy initialization of network link service (see bug 620472)
             InitializeNetworkLinkService();
@@ -944,22 +945,23 @@ nsIOService::Observe(nsISupports *subjec
         // changes of the offline status from now. We must not allow going
         // online after this point.
         mShutdown = true;
 
         SetOffline(true);
 
         // Break circular reference.
         mProxyService = nullptr;
-    } else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
+    }
+    else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
         if (!mOfflineForProfileChange && mManageOfflineStatus) {
-            OnNetworkLinkEvent(NS_ConvertUTF16toUTF8(data).get());
+            TrackNetworkLinkStatusForOffline();
         }
     }
-
+    
     return NS_OK;
 }
 
 // nsINetUtil interface
 NS_IMETHODIMP
 nsIOService::ParseContentType(const nsACString &aTypeHeader,
                               nsACString &aCharset,
                               bool *aHadCharset,
@@ -1047,98 +1049,81 @@ nsIOService::NewSimpleNestedURI(nsIURI* 
     nsresult rv = NS_EnsureSafeToReturn(aURI, getter_AddRefs(safeURI));
     NS_ENSURE_SUCCESS(rv, rv);
 
     NS_IF_ADDREF(*aResult = new nsSimpleNestedURI(safeURI));
     return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
-nsIOService::SetManageOfflineStatus(bool aManage)
-{
+nsIOService::SetManageOfflineStatus(bool aManage) {
     nsresult rv = NS_OK;
 
     // SetManageOfflineStatus must throw when we fail to go from non-managed
-    // to managed.  Usually because there is no link monitoring service
-    // available.  Failure to do this switch is detected by a failure of
-    // OnNetworkLinkEvent().  When there is no network link available during
-    // call to InitializeNetworkLinkService(), application is put to offline
-    // mode.  And when we change mMangeOfflineStatus to false on the next line
-    // we get stuck on being offline even though the link becomes later
-    // available.
+    // to managed.  Usually because there is no link monitoring service 
+    // available.  Failure to do this switch is detected by a failure of 
+    // TrackNetworkLinkStatusForOffline().  When there is no network link 
+    // available during call to InitializeNetworkLinkService(), application is
+    // put to offline mode.  And when we change mMangeOfflineStatus to false 
+    // on the next line we get stuck on being offline even though the link 
+    // becomes later available.
     bool wasManaged = mManageOfflineStatus;
     mManageOfflineStatus = aManage;
 
     InitializeNetworkLinkService();
 
     if (mManageOfflineStatus && !wasManaged) {
-        rv = OnNetworkLinkEvent(NS_NETWORK_LINK_DATA_UNKNOWN);
+        rv = TrackNetworkLinkStatusForOffline();
         if (NS_FAILED(rv))
             mManageOfflineStatus = false;
     }
     return rv;
 }
 
 NS_IMETHODIMP
 nsIOService::GetManageOfflineStatus(bool* aManage) {
     *aManage = mManageOfflineStatus;
     return NS_OK;
 }
 
-// input argument 'data' is already UTF8'ed
 nsresult
-nsIOService::OnNetworkLinkEvent(const char *data)
+nsIOService::TrackNetworkLinkStatusForOffline()
 {
+    NS_ASSERTION(mManageOfflineStatus,
+                 "Don't call this unless we're managing the offline status");
     if (!mNetworkLinkService)
         return NS_ERROR_FAILURE;
 
     if (mShutdown)
         return NS_ERROR_NOT_AVAILABLE;
-
-    if (mManageOfflineStatus)
-        return NS_OK;
-
-    if (!strcmp(data, NS_NETWORK_LINK_DATA_DOWN)) {
-        // check to make sure this won't collide with Autodial
-        if (mSocketTransportService) {
-            bool autodialEnabled = false;
-            mSocketTransportService->GetAutodialEnabled(&autodialEnabled);
-            // If autodialing-on-link-down is enabled, check if the OS auto
-            // dial option is set to always autodial. If so, then we are
-            // always up for the purposes of offline management.
-            if (autodialEnabled) {
+  
+    // check to make sure this won't collide with Autodial
+    if (mSocketTransportService) {
+        bool autodialEnabled = false;
+        mSocketTransportService->GetAutodialEnabled(&autodialEnabled);
+        // If autodialing-on-link-down is enabled, check if the OS auto dial 
+        // option is set to always autodial. If so, then we are 
+        // always up for the purposes of offline management.
+        if (autodialEnabled) {
 #if defined(XP_WIN)
-                // On Windows, we should first check with the OS to see if
-                // autodial is enabled.  If it is enabled then we are allowed
-                // to manage the offline state.
-                if (nsNativeConnectionHelper::IsAutodialEnabled()) {
-                    return SetOffline(false);
-                }
+            // On Windows, we should first check with the OS
+            // to see if autodial is enabled.  If it is
+            // enabled then we are allowed to manage the
+            // offline state.
+            if(nsNativeConnectionHelper::IsAutodialEnabled()) 
+                return SetOffline(false);
 #else
-                return SetOffline(false);
+            return SetOffline(false);
 #endif
-            }
         }
     }
 
     bool isUp;
-    if (!strcmp(data, NS_NETWORK_LINK_DATA_DOWN)) {
-        isUp = false;
-    } else if (!strcmp(data, NS_NETWORK_LINK_DATA_UP)) {
-        isUp = true;
-    } else if (!strcmp(data, NS_NETWORK_LINK_DATA_CHANGED)) {
-        // CHANGED events are handled by others
-        return NS_OK;
-    } else if (!strcmp(data, NS_NETWORK_LINK_DATA_UNKNOWN)) {
-        nsresult rv = mNetworkLinkService->GetIsLinkUp(&isUp);
-        NS_ENSURE_SUCCESS(rv, rv);
-    } else {
-        NS_WARNING("Unhandled network event!");
-        return NS_OK;
-    }
+    nsresult rv = mNetworkLinkService->GetIsLinkUp(&isUp);
+    NS_ENSURE_SUCCESS(rv, rv);
     return SetOffline(!isUp);
 }
 
 NS_IMETHODIMP
 nsIOService::EscapeString(const nsACString& aString,
                           uint32_t aEscapeType,
                           nsACString& aResult)
 {
--- a/netwerk/base/src/nsIOService.h
+++ b/netwerk/base/src/nsIOService.h
@@ -76,17 +76,17 @@ public:
 
 private:
     // These shouldn't be called directly:
     // - construct using GetInstance
     // - destroy using Release
     nsIOService();
     ~nsIOService();
 
-    nsresult OnNetworkLinkEvent(const char *data);
+    nsresult TrackNetworkLinkStatusForOffline();
 
     nsresult GetCachedProtocolHandler(const char *scheme,
                                                   nsIProtocolHandler* *hdlrResult,
                                                   uint32_t start=0,
                                                   uint32_t end=0);
     nsresult CacheProtocolHandler(const char *scheme,
                                               nsIProtocolHandler* hdlr);
 
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -25,25 +25,22 @@
 #include "prnetdb.h"
 #include "prmon.h"
 #include "prio.h"
 #include "plstr.h"
 #include "nsIOService.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsNetAddr.h"
 #include "nsProxyRelease.h"
-#include "nsIObserverService.h"
-#include "nsINetworkLinkService.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/VisualEventTracer.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "mozilla/net/ChildDNSService.h"
 #include "mozilla/net/DNSListenerProxy.h"
-#include "mozilla/Services.h"
 
 using namespace mozilla;
 using namespace mozilla::net;
 
 static const char kPrefDnsCacheEntries[]     = "network.dnsCacheEntries";
 static const char kPrefDnsCacheExpiration[]  = "network.dnsCacheExpiration";
 static const char kPrefDnsCacheGrace[]       = "network.dnsCacheExpirationGracePeriod";
 static const char kPrefIPv4OnlyDomains[]     = "network.dns.ipv4OnlyDomains";
@@ -538,23 +535,22 @@ nsDNSService::Init()
             prefs->AddObserver(kPrefDisablePrefetch, this, false);
             prefs->AddObserver(kPrefDnsNotifyResolution, 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);
         }
 
+        nsresult rv;
         nsCOMPtr<nsIObserverService> observerService =
-            mozilla::services::GetObserverService();
-        if (observerService) {
+            do_GetService("@mozilla.org/observer-service;1", &rv);
+        if (NS_SUCCEEDED(rv)) {
             observerService->AddObserver(this, "last-pb-context-exited", false);
-            observerService->AddObserver(this, NS_NETWORK_LINK_TOPIC, false);
         }
-
     }
 
     nsDNSPrefetch::Initialize(this);
 
     // Don't initialize the resolver if we're in offline mode.
     // Later on, the IO service will reinitialize us when going online.
     if (gIOService->IsOffline() && !gIOService->IsComingOnline())
         return NS_OK;
@@ -869,30 +865,20 @@ nsDNSService::GetMyHostName(nsACString &
         return NS_OK;
     }
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsDNSService::Observe(nsISupports *subject, const char *topic, const char16_t *data)
 {
-    // We are only getting called if a preference has changed or there's a
-    // network link event.
+    // we are only getting called if a preference has changed. 
     NS_ASSERTION(strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0 ||
-                 strcmp(topic, "last-pb-context-exited") == 0 ||
-                 strcmp(topic, NS_NETWORK_LINK_TOPIC) == 0,
-                 "unexpected observe call");
-
-    if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
-        nsAutoCString converted = NS_ConvertUTF16toUTF8(data);
-        if (!strcmp(converted.get(), NS_NETWORK_LINK_DATA_CHANGED)) {
-            mResolver->FlushCache();
-        }
-        return NS_OK;
-    }
+        strcmp(topic, "last-pb-context-exited") == 0,
+        "unexpected observe call");
 
     //
     // Shutdown and this function are both only called on the UI thread, so we don't
     // have to worry about mResolver being cleared out from under us.
     //
     // NOTE Shutting down and reinitializing the service like this is obviously
     // suboptimal if Observe gets called several times in a row, but we don't
     // expect that to be the case.
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -463,31 +463,16 @@ nsHostRecord::GetPriority(uint16_t aFlag
         return nsHostRecord::DNS_PRIORITY_HIGH;
     } else if (IsMediumPriority(aFlags)) {
         return nsHostRecord::DNS_PRIORITY_MEDIUM;
     }
 
     return nsHostRecord::DNS_PRIORITY_LOW;
 }
 
-// Returns true if the entry can be removed, or false if it was marked to get
-// refreshed.
-bool
-nsHostRecord::RemoveOrRefresh()
-{
-  // This condition implies that 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.
-    if (resolving && !onQueue) {
-        mResolveAgain = true;
-        return false;
-    }
-    return true; // can be removed now
-}
-
 //----------------------------------------------------------------------------
 
 struct nsHostDBEnt : PLDHashEntryHdr
 {
     nsHostRecord *rec;
 };
 
 static PLDHashNumber
@@ -591,31 +576,16 @@ static PLDHashOperator
 HostDB_RemoveEntry(PLDHashTable *table,
                    PLDHashEntryHdr *hdr,
                    uint32_t number,
                    void *arg)
 {
     return PL_DHASH_REMOVE;
 }
 
-static PLDHashOperator
-HostDB_PruneEntry(PLDHashTable *table,
-                  PLDHashEntryHdr *hdr,
-                  uint32_t number,
-                  void *arg)
-{
-    nsHostDBEnt* ent = static_cast<nsHostDBEnt *>(hdr);
-
-    // Try to remove the record, or mark it for refresh
-    if (ent->rec->RemoveOrRefresh()) {
-        return PL_DHASH_REMOVE;
-    }
-    return PL_DHASH_NEXT;
-}
-
 //----------------------------------------------------------------------------
 
 #if TTL_AVAILABLE
 static const char kTtlExperimentEnabled[] = "dns.ttl-experiment.enabled";
 static const char kNetworkExperimentsEnabled[] = "network.allow-experiments";
 static const char kTtlExperimentVariant[] = "dns.ttl-experiment.variant";
 
 
@@ -771,51 +741,16 @@ nsHostResolver::ClearPendingQueue(PRCLis
         while (node != aPendingQ) {
             nsHostRecord *rec = static_cast<nsHostRecord *>(node);
             node = node->next;
             OnLookupComplete(rec, NS_ERROR_ABORT, nullptr);
         }
     }
 }
 
-//
-// FlushCache() is what we call when the network has changed. We must not
-// 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()
-{
-    PRCList evictionQ;
-    PR_INIT_CLIST(&evictionQ);
-
-    {
-        MutexAutoLock lock(mLock);
-        MoveCList(mEvictionQ, evictionQ);
-        mEvictionQSize = 0;
-
-        // prune the hash from all hosts already resolved
-        PL_DHashTableEnumerate(&mDB, HostDB_PruneEntry, nullptr);
-    }
-
-    if (!PR_CLIST_IS_EMPTY(&evictionQ)) {
-        PRCList *node = evictionQ.next;
-        while (node != &evictionQ) {
-            nsHostRecord *rec = static_cast<nsHostRecord *>(node);
-            node = node->next;
-            NS_RELEASE(rec);
-        }
-    }
-}
-
 void
 nsHostResolver::Shutdown()
 {
     LOG(("Shutting down host resolver.\n"));
 
 #if TTL_AVAILABLE
     {
         DebugOnly<nsresult> rv = Preferences::UnregisterCallback(
@@ -832,33 +767,33 @@ nsHostResolver::Shutdown()
     PRCList pendingQHigh, pendingQMed, pendingQLow, evictionQ;
     PR_INIT_CLIST(&pendingQHigh);
     PR_INIT_CLIST(&pendingQMed);
     PR_INIT_CLIST(&pendingQLow);
     PR_INIT_CLIST(&evictionQ);
 
     {
         MutexAutoLock lock(mLock);
-
+        
         mShutdown = true;
 
         MoveCList(mHighQ, pendingQHigh);
         MoveCList(mMediumQ, pendingQMed);
         MoveCList(mLowQ, pendingQLow);
         MoveCList(mEvictionQ, evictionQ);
         mEvictionQSize = 0;
         mPendingCount = 0;
-
+        
         if (mNumIdleThreads)
             mIdleThreadCV.NotifyAll();
-
+        
         // empty host database
         PL_DHashTableEnumerate(&mDB, HostDB_RemoveEntry, nullptr);
     }
-
+    
     ClearPendingQueue(&pendingQHigh);
     ClearPendingQueue(&pendingQMed);
     ClearPendingQueue(&pendingQLow);
 
     if (!PR_CLIST_IS_EMPTY(&evictionQ)) {
         PRCList *node = evictionQ.next;
         while (node != &evictionQ) {
             nsHostRecord *rec = static_cast<nsHostRecord *>(node);
@@ -1391,36 +1326,26 @@ nsHostResolver::PrepareRecordExpiration(
             break;
     }
 
     rec->SetExpiration(TimeStamp::NowLoRes(), lifetime, grace);
     LOG(("Caching [%s] record for %u seconds (grace %d) (sDnsVariant = %d).",
          rec->host, lifetime, grace, sDnsVariant));
 }
 
-//
-// OnLookupComplete() checks if the resolving should be redone and if so it
-// returns LOOKUP_RESOLVEAGAIN, but only if 'status' is not NS_ERROR_ABORT.
-//
-
-nsHostResolver::LookupStatus
+void
 nsHostResolver::OnLookupComplete(nsHostRecord* rec, nsresult status, AddrInfo* result)
 {
     // get the list of pending callbacks for this lookup, and notify
     // them that the lookup is complete.
     PRCList cbs;
     PR_INIT_CLIST(&cbs);
     {
         MutexAutoLock lock(mLock);
 
-        if (rec->mResolveAgain && (status != NS_ERROR_ABORT)) {
-            rec->mResolveAgain = false;
-            return LOOKUP_RESOLVEAGAIN;
-        }
-
         // grab list of callbacks to notify
         MoveCList(rec->callbacks, cbs);
 
         // update record fields.  We might have a rec->addr_info already if a
         // previous lookup result expired and we're reresolving it..
         AddrInfo  *old_addr_info;
         {
             MutexAutoLock lock(rec->addr_info_lock);
@@ -1489,18 +1414,16 @@ nsHostResolver::OnLookupComplete(nsHostR
             DebugOnly<nsresult> rv = IssueLookup(rec);
             NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
                              "Could not issue second async lookup for TTL.");
         }
     }
 #endif
 
     NS_RELEASE(rec);
-
-    return LOOKUP_OK;
 }
 
 void
 nsHostResolver::CancelAsyncRequest(const char            *host,
                                    uint16_t               flags,
                                    uint16_t               af,
                                    nsIDNSListener        *aListener,
                                    nsresult               status)
@@ -1574,20 +1497,19 @@ nsHostResolver::ThreadFunc(void *arg)
 
     static nsThreadPoolNaming naming;
     naming.SetThreadPoolName(NS_LITERAL_CSTRING("DNS Resolver"));
 
 #if defined(RES_RETRY_ON_FAILURE)
     nsResState rs;
 #endif
     nsHostResolver *resolver = (nsHostResolver *)arg;
-    nsHostRecord *rec  = nullptr;
+    nsHostRecord *rec;
     AddrInfo *ai = nullptr;
-
-    while (rec || resolver->GetHostToLookup(&rec)) {
+    while (resolver->GetHostToLookup(&rec)) {
         LOG(("DNS lookup thread - Calling getaddrinfo for host [%s].\n",
              rec->host));
 
         int flags = PR_AI_ADDRCONFIG;
         if (!(rec->flags & RES_CANON_NAME))
             flags |= PR_AI_NOCANONNAME;
 
         TimeStamp startTime = TimeStamp::Now();
@@ -1621,23 +1543,17 @@ nsHostResolver::ThreadFunc(void *arg)
         }
         else {
             Telemetry::Accumulate(Telemetry::DNS_FAILED_LOOKUP_TIME, millis);
         }
 
         // OnLookupComplete may release "rec", long before we lose it.
         LOG(("DNS lookup thread - lookup completed for host [%s]: %s.\n",
              rec->host, ai ? "success" : "failure: unknown host"));
-        if (LOOKUP_RESOLVEAGAIN == resolver->OnLookupComplete(rec, status, ai)) {
-            // leave 'rec' assigned and loop to make a renewed host resolve
-            LOG(("DNS lookup thread - Re-resolving host [%s].\n",
-                 rec->host));
-        } else {
-            rec = nullptr;
-        }
+        resolver->OnLookupComplete(rec, status, ai);
     }
     NS_RELEASE(resolver);
     LOG(("DNS lookup thread - queue empty, thread finished.\n"));
 }
 
 nsresult
 nsHostResolver::Create(uint32_t maxCacheEntries,
                        uint32_t defaultCacheEntryLifetime,
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -114,19 +114,16 @@ public:
 
     enum DnsPriority {
         DNS_PRIORITY_LOW,
         DNS_PRIORITY_MEDIUM,
         DNS_PRIORITY_HIGH,
     };
     static DnsPriority GetPriority(uint16_t aFlags);
 
-    bool RemoveOrRefresh(); // Returns whether the host record can be removed
-                            // or needs to be refreshed
-
 private:
     friend class nsHostResolver;
 
 
     PRCList callbacks; /* list of callbacks */
 
     bool    resolving; /* true if this record is being resolved, which means
                         * that it is either on the pending queue or owned by
@@ -139,20 +136,16 @@ private:
 #if TTL_AVAILABLE
     bool    mGetTtl;
 #endif
 
     // The number of times ReportUnusable() has been called in the record's
     // lifetime.
     uint32_t mBlacklistedCount;
 
-    // when the results from this resolve is returned, it is not to be
-    // trusted, but instead a new resolve must be made!
-    bool    mResolveAgain;
-
     // 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
     // of gencnt.
     nsTArray<nsCString> mBlacklistedItems;
 
     explicit nsHostRecord(const nsHostKey *key);           /* use Create() instead */
    ~nsHostRecord();
 };
@@ -280,37 +273,26 @@ public:
         RES_PRIORITY_LOW  = 1 << 3,
         RES_SPECULATE     = 1 << 4,
         //RES_DISABLE_IPV6 = 1 << 5, // Not used
         RES_OFFLINE       = 1 << 6
     };
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
-    /**
-     * Flush the DNS cache.
-     */
-    void FlushCache();
-
 private:
    explicit nsHostResolver(uint32_t maxCacheEntries,
                            uint32_t defaultCacheEntryLifetime,
                            uint32_t defaultGracePeriod);
    ~nsHostResolver();
 
     nsresult Init();
     nsresult IssueLookup(nsHostRecord *);
     bool     GetHostToLookup(nsHostRecord **m);
-
-    enum LookupStatus {
-      LOOKUP_OK,
-      LOOKUP_RESOLVEAGAIN,
-    };
-
-    LookupStatus OnLookupComplete(nsHostRecord *, nsresult, mozilla::net::AddrInfo *);
+    void     OnLookupComplete(nsHostRecord *, nsresult, mozilla::net::AddrInfo *);
     void     DeQueue(PRCList &aQ, nsHostRecord **aResult);
     void     ClearPendingQueue(PRCList *aPendingQueue);
     nsresult ConditionallyCreateThread(nsHostRecord *rec);
 
     /**
      * Starts a new lookup in the background for entries that are in the grace
      * period with a failed connect or all cached entries are negative.
      */
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -42,17 +42,16 @@
 #include "nsIObserverService.h"
 #include "nsISiteSecurityService.h"
 #include "nsIStreamConverterService.h"
 #include "nsITimer.h"
 #include "nsCRT.h"
 #include "SpdyZlibReporter.h"
 #include "nsIMemoryReporter.h"
 #include "nsIParentalControlsService.h"
-#include "nsINetworkLinkService.h"
 
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/Telemetry.h"
 
 #if defined(XP_UNIX)
 #include <sys/utsname.h>
 #endif
 
@@ -344,17 +343,16 @@ nsHttpHandler::Init()
         mObserverService->AddObserver(this, "profile-change-net-teardown", true);
         mObserverService->AddObserver(this, "profile-change-net-restore", true);
         mObserverService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
         mObserverService->AddObserver(this, "net:clear-active-logins", true);
         mObserverService->AddObserver(this, "net:prune-dead-connections", true);
         mObserverService->AddObserver(this, "net:failed-to-process-uri-content", true);
         mObserverService->AddObserver(this, "last-pb-context-exited", true);
         mObserverService->AddObserver(this, "browser:purge-session-history", true);
-        mObserverService->AddObserver(this, NS_NETWORK_LINK_TOPIC, false);
     }
 
     MakeNewRequestTokenBucket();
     mWifiTickler = new Tickler();
     if (NS_FAILED(mWifiTickler->Init()))
         mWifiTickler = nullptr;
 
     nsCOMPtr<nsIParentalControlsService> pc = do_CreateInstance("@mozilla.org/parental-controls-service;1");
@@ -1777,22 +1775,23 @@ nsHttpHandler::GetMisc(nsACString &value
 
 NS_IMETHODIMP
 nsHttpHandler::Observe(nsISupports *subject,
                        const char *topic,
                        const char16_t *data)
 {
     LOG(("nsHttpHandler::Observe [topic=\"%s\"]\n", topic));
 
-    if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
+    if (strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
         nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject);
         if (prefBranch)
             PrefsChanged(prefBranch, NS_ConvertUTF16toUTF8(data).get());
-    } else if (!strcmp(topic, "profile-change-net-teardown") ||
-               !strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) ) {
+    }
+    else if (strcmp(topic, "profile-change-net-teardown")    == 0 ||
+             strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)    == 0) {
 
         mHandlerActive = false;
 
         // clear cache of all authentication credentials.
         mAuthCache.ClearAll();
         mPrivateAuthCache.ClearAll();
         if (mWifiTickler)
             mWifiTickler->Cancel();
@@ -1802,49 +1801,47 @@ nsHttpHandler::Observe(nsISupports *subj
             mConnMgr->Shutdown();
 
         // need to reset the session start time since cache validation may
         // depend on this value.
         mSessionStartTime = NowInSeconds();
 
         if (!mDoNotTrackEnabled) {
             Telemetry::Accumulate(Telemetry::DNT_USAGE, DONOTTRACK_VALUE_UNSET);
-        } else {
+        }
+        else {
             Telemetry::Accumulate(Telemetry::DNT_USAGE, mDoNotTrackValue);
         }
-    } else if (!strcmp(topic, "profile-change-net-restore")) {
+    }
+    else if (strcmp(topic, "profile-change-net-restore") == 0) {
         // initialize connection manager
         InitConnectionMgr();
-    } else if (!strcmp(topic, "net:clear-active-logins")) {
+    }
+    else if (strcmp(topic, "net:clear-active-logins") == 0) {
         mAuthCache.ClearAll();
         mPrivateAuthCache.ClearAll();
-    } else if (!strcmp(topic, "net:prune-dead-connections")) {
+    }
+    else if (strcmp(topic, "net:prune-dead-connections") == 0) {
         if (mConnMgr) {
             mConnMgr->PruneDeadConnections();
         }
-    } else if (!strcmp(topic, "net:failed-to-process-uri-content")) {
+    }
+    else if (strcmp(topic, "net:failed-to-process-uri-content") == 0) {
         nsCOMPtr<nsIURI> uri = do_QueryInterface(subject);
-        if (uri && mConnMgr) {
+        if (uri && mConnMgr)
             mConnMgr->ReportFailedToProcess(uri);
-        }
-    } else if (!strcmp(topic, "last-pb-context-exited")) {
+    }
+    else if (strcmp(topic, "last-pb-context-exited") == 0) {
         mPrivateAuthCache.ClearAll();
-    } else if (!strcmp(topic, "browser:purge-session-history")) {
+    } else if (strcmp(topic, "browser:purge-session-history") == 0) {
         if (mConnMgr && gSocketTransportService) {
             nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(mConnMgr,
                 &nsHttpConnectionMgr::ClearConnectionHistory);
             gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL);
         }
-    } else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
-        nsAutoCString converted = NS_ConvertUTF16toUTF8(data);
-        if (!strcmp(converted.get(), NS_NETWORK_LINK_DATA_CHANGED)) {
-            if (mConnMgr) {
-                mConnMgr->PruneDeadConnections();
-            }
-        }
     }
 
     return NS_OK;
 }
 
 // nsISpeculativeConnect
 
 NS_IMETHODIMP
--- a/netwerk/system/win32/nsNotifyAddrListener.cpp
+++ b/netwerk/system/win32/nsNotifyAddrListener.cpp
@@ -7,21 +7,16 @@
 #include <stdarg.h>
 #include <windef.h>
 #include <winbase.h>
 #include <wingdi.h>
 #include <winuser.h>
 #include <ole2.h>
 #include <netcon.h>
 #include <objbase.h>
-#include <winsock2.h>
-#include <ws2ipdef.h>
-#include <tcpmib.h>
-#include <iphlpapi.h>
-#include <netioapi.h>
 #include <iprtrmib.h>
 #include "plstr.h"
 #include "nsThreadUtils.h"
 #include "nsIObserverService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsNotifyAddrListener.h"
 #include "nsString.h"
 #include "nsAutoPtr.h"
@@ -29,36 +24,16 @@
 #include "nsCRT.h"
 
 #include <iptypes.h>
 #include <iphlpapi.h>
 
 static HMODULE sNetshell;
 static decltype(NcFreeNetconProperties)* sNcFreeNetconProperties;
 
-static HMODULE sIphlpapi;
-static decltype(NotifyIpInterfaceChange)* sNotifyIpInterfaceChange;
-static decltype(CancelMibChangeNotify2)* sCancelMibChangeNotify2;
-
-static void InitIphlpapi(void)
-{
-    if (!sIphlpapi) {
-        sIphlpapi = LoadLibraryW(L"Iphlpapi.dll");
-        if (sIphlpapi) {
-            sNotifyIpInterfaceChange = (decltype(NotifyIpInterfaceChange)*)
-                GetProcAddress(sIphlpapi, "NotifyIpInterfaceChange");
-            sCancelMibChangeNotify2 = (decltype(CancelMibChangeNotify2)*)
-                GetProcAddress(sIphlpapi, "CancelMibChangeNotify2");
-        } else {
-            NS_WARNING("Failed to load Iphlpapi.dll - cannot detect network"
-                       " changes!");
-        }
-    }
-}
-
 static void InitNetshellLibrary(void)
 {
     if (!sNetshell) {
         sNetshell = LoadLibraryW(L"Netshell.dll");
         if (sNetshell) {
             sNcFreeNetconProperties = (decltype(NcFreeNetconProperties)*)
                 GetProcAddress(sNetshell, "NcFreeNetconProperties");
         }
@@ -67,37 +42,29 @@ static void InitNetshellLibrary(void)
 
 static void FreeDynamicLibraries(void)
 {
     if (sNetshell) {
         sNcFreeNetconProperties = nullptr;
         FreeLibrary(sNetshell);
         sNetshell = nullptr;
     }
-    if (sIphlpapi) {
-        sNotifyIpInterfaceChange = nullptr;
-        sCancelMibChangeNotify2 = nullptr;
-        FreeLibrary(sIphlpapi);
-        sIphlpapi = nullptr;
-    }
 }
 
 NS_IMPL_ISUPPORTS(nsNotifyAddrListener,
                   nsINetworkLinkService,
                   nsIRunnable,
                   nsIObserver)
 
 nsNotifyAddrListener::nsNotifyAddrListener()
     : mLinkUp(true)  // assume true by default
     , mStatusKnown(false)
     , mCheckAttempted(false)
     , mShutdownEvent(nullptr)
-    , mIPInterfaceChecksum(0)
 {
-    InitIphlpapi();
 }
 
 nsNotifyAddrListener::~nsNotifyAddrListener()
 {
     NS_ASSERTION(!mThread, "nsNotifyAddrListener thread shutdown failed");
     FreeDynamicLibraries();
 }
 
@@ -125,75 +92,46 @@ nsNotifyAddrListener::GetLinkType(uint32
 {
   NS_ENSURE_ARG_POINTER(aLinkType);
 
   // XXX This function has not yet been implemented for this platform
   *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
   return NS_OK;
 }
 
-// Static Callback function for NotifyIpInterfaceChange API.
-static void WINAPI OnInterfaceChange(PVOID callerContext,
-                                     PMIB_IPINTERFACE_ROW row,
-                                     MIB_NOTIFICATION_TYPE notificationType)
-{
-    nsNotifyAddrListener *notify = static_cast<nsNotifyAddrListener*>(callerContext);
-    notify->CheckLinkStatus();
-}
-
 NS_IMETHODIMP
 nsNotifyAddrListener::Run()
 {
     PR_SetCurrentThreadName("Link Monitor");
 
-    mChangedTime = TimeStamp::Now();
+    HANDLE ev = CreateEvent(nullptr, FALSE, FALSE, nullptr);
+    NS_ENSURE_TRUE(ev, NS_ERROR_OUT_OF_MEMORY);
 
-    if (!sNotifyIpInterfaceChange || !sCancelMibChangeNotify2) {
-        // For Windows versions which are older than Vista which lack
-        // NotifyIpInterfaceChange. Note this means no IPv6 support.
-        HANDLE ev = CreateEvent(nullptr, FALSE, FALSE, nullptr);
-        NS_ENSURE_TRUE(ev, NS_ERROR_OUT_OF_MEMORY);
-
-        HANDLE handles[2] = { ev, mShutdownEvent };
-        OVERLAPPED overlapped = { 0 };
-        bool shuttingDown = false;
+    HANDLE handles[2] = { ev, mShutdownEvent };
+    OVERLAPPED overlapped = { 0 };
+    bool shuttingDown = false;
 
-        overlapped.hEvent = ev;
-        while (!shuttingDown) {
-            HANDLE h;
-            DWORD ret = NotifyAddrChange(&h, &overlapped);
+    overlapped.hEvent = ev;
+    while (!shuttingDown) {
+        HANDLE h;
+        DWORD ret = NotifyAddrChange(&h, &overlapped);
 
-            if (ret == ERROR_IO_PENDING) {
-                ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
-                if (ret == WAIT_OBJECT_0) {
-                    CheckLinkStatus();
-                } else {
-                    shuttingDown = true;
-                }
+        if (ret == ERROR_IO_PENDING) {
+            ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+            if (ret == WAIT_OBJECT_0) {
+                CheckLinkStatus();
             } else {
                 shuttingDown = true;
             }
+        } else {
+            shuttingDown = true;
         }
-        CloseHandle(ev);
-    } else {
-        // Windows Vista and newer versions.
-        HANDLE interfacechange;
-        // The callback will simply invoke CheckLinkStatus()
-        DWORD ret = sNotifyIpInterfaceChange(
-            AF_UNSPEC, // IPv4 and IPv6
-            (PIPINTERFACE_CHANGE_CALLBACK)OnInterfaceChange,
-            this,  // pass to callback
-            false, // no initial notification
-            &interfacechange);
+    }
+    CloseHandle(ev);
 
-        if (ret == NO_ERROR) {
-            ret = WaitForSingleObject(mShutdownEvent, INFINITE);
-        }
-        sCancelMibChangeNotify2(interfacechange);
-    }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNotifyAddrListener::Observe(nsISupports *subject,
                               const char *topic,
                               const char16_t *data)
 {
@@ -246,21 +184,21 @@ nsNotifyAddrListener::Shutdown(void)
     mThread = nullptr;
 
     CloseHandle(mShutdownEvent);
     mShutdownEvent = nullptr;
 
     return rv;
 }
 
-/* Sends the given event.  Assumes aEventID never goes out of scope (static
- * strings are ideal).
+/* Sends the given event to the UI thread.  Assumes aEventID never goes out
+ * of scope (static strings are ideal).
  */
 nsresult
-nsNotifyAddrListener::SendEvent(const char *aEventID)
+nsNotifyAddrListener::SendEventToUI(const char *aEventID)
 {
     if (!aEventID)
         return NS_ERROR_NULL_POINTER;
 
     nsresult rv;
     nsCOMPtr<nsIRunnable> event = new ChangeEvent(this, aEventID);
     if (NS_FAILED(rv = NS_DispatchToMainThread(event)))
         NS_WARNING("Failed to dispatch ChangeEvent");
@@ -274,22 +212,18 @@ nsNotifyAddrListener::ChangeEvent::Run()
         mozilla::services::GetObserverService();
     if (observerService)
         observerService->NotifyObservers(
                 mService, NS_NETWORK_LINK_TOPIC,
                 NS_ConvertASCIItoUTF16(mEventID).get());
     return NS_OK;
 }
 
-
-// Bug 465158 features an explanation for this check. ICS being "Internet
-// Connection Sharing). The description says it is always IP address
-// 192.168.0.1 for this case.
 bool
-nsNotifyAddrListener::CheckICSGateway(PIP_ADAPTER_ADDRESSES aAdapter)
+nsNotifyAddrListener::CheckIsGateway(PIP_ADAPTER_ADDRESSES aAdapter)
 {
     if (!aAdapter->FirstUnicastAddress)
         return false;
 
     LPSOCKADDR aAddress = aAdapter->FirstUnicastAddress->Address.lpSockaddr;
     if (!aAddress)
         return false;
 
@@ -381,134 +315,77 @@ nsNotifyAddrListener::CheckICSStatus(PWC
     return isICSGatewayAdapter;
 }
 
 DWORD
 nsNotifyAddrListener::CheckAdaptersAddresses(void)
 {
     ULONG len = 16384;
 
-    PIP_ADAPTER_ADDRESSES adapterList = (PIP_ADAPTER_ADDRESSES) moz_xmalloc(len);
-
-    ULONG flags = GAA_FLAG_SKIP_DNS_SERVER|GAA_FLAG_SKIP_MULTICAST|
-        GAA_FLAG_SKIP_ANYCAST;
+    PIP_ADAPTER_ADDRESSES addresses = (PIP_ADAPTER_ADDRESSES) malloc(len);
+    if (!addresses)
+        return ERROR_OUTOFMEMORY;
 
-    DWORD ret = GetAdaptersAddresses(AF_UNSPEC, flags, nullptr, adapterList, &len);
+    DWORD ret = GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, addresses, &len);
     if (ret == ERROR_BUFFER_OVERFLOW) {
-        free(adapterList);
-        adapterList = static_cast<PIP_ADAPTER_ADDRESSES> (moz_xmalloc(len));
-
-        ret = GetAdaptersAddresses(AF_UNSPEC, flags, nullptr, adapterList, &len);
+        free(addresses);
+        addresses = (PIP_ADAPTER_ADDRESSES) malloc(len);
+        if (!addresses)
+            return ERROR_BUFFER_OVERFLOW;
+        ret = GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, addresses, &len);
     }
 
     if (FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED))) {
-        free(adapterList);
+        free(addresses);
         return ERROR_NOT_SUPPORTED;
     }
 
-    //
-    // Since NotifyIpInterfaceChange() signals a change more often than we
-    // think is a worthy change, we checksum the entire state of all interfaces
-    // that are UP. If the checksum is the same as previous check, nothing
-    // of interest changed!
-    //
-    ULONG sum = 0;
-
     if (ret == ERROR_SUCCESS) {
+        PIP_ADAPTER_ADDRESSES ptr;
         bool linkUp = false;
 
-        for (PIP_ADAPTER_ADDRESSES adapter = adapterList; adapter;
-             adapter = adapter->Next) {
-            if (adapter->OperStatus != IfOperStatusUp ||
-                !adapter->FirstUnicastAddress ||
-                adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK ||
-                CheckICSGateway(adapter) ) {
-                continue;
-            }
-
-            // Add chars from AdapterName to the checksum.
-            for (int i = 0; adapter->AdapterName[i]; ++i) {
-                sum <<= 2;
-                sum += adapter->AdapterName[i];
-            }
-
-            // Add bytes from each socket address to the checksum.
-            for (PIP_ADAPTER_UNICAST_ADDRESS pip = adapter->FirstUnicastAddress;
-                 pip; pip = pip->Next) {
-                SOCKET_ADDRESS *sockAddr = &pip->Address;
-                for (int i = 0; i < sockAddr->iSockaddrLength; ++i) {
-                    sum += (reinterpret_cast<unsigned char *>
-                            (sockAddr->lpSockaddr))[i];
-                }
-            }
-            linkUp = true;
+        for (ptr = addresses; !linkUp && ptr; ptr = ptr->Next) {
+            if (ptr->OperStatus == IfOperStatusUp &&
+                    ptr->IfType != IF_TYPE_SOFTWARE_LOOPBACK &&
+                    !CheckIsGateway(ptr))
+                linkUp = true;
         }
         mLinkUp = linkUp;
         mStatusKnown = true;
     }
-    free(adapterList);
-
-    if (mLinkUp) {
-        /* Store the checksum only if one or more interfaces are up */
-        mIPInterfaceChecksum = sum;
-    }
+    free(addresses);
 
     CoUninitialize();
 
     return ret;
 }
 
 /**
  * Checks the status of all network adapters.  If one is up and has a valid IP
  * address, sets mLinkUp to true.  Sets mStatusKnown to true if the link status
  * is definitive.
  */
 void
 nsNotifyAddrListener::CheckLinkStatus(void)
 {
     DWORD ret;
     const char *event;
-    bool prevLinkUp = mLinkUp;
-    ULONG prevCsum = mIPInterfaceChecksum;
 
-    // The CheckAdaptersAddresses call is very expensive (~650 milliseconds),
-    // so we don't want to call it synchronously. Instead, we just start up
-    // assuming we have a network link, but we'll report that the status is
-    // unknown.
+    // This call is very expensive (~650 milliseconds), so we don't want to
+    // call it synchronously. Instead, we just start up assuming we have a
+    // network link, but we'll report that the status is unknown.
     if (NS_IsMainThread()) {
         NS_WARNING("CheckLinkStatus called on main thread! No check "
                    "performed. Assuming link is up, status is unknown.");
         mLinkUp = true;
-
-        if (!mStatusKnown) {
-            event = NS_NETWORK_LINK_DATA_UNKNOWN;
-        } else if (!prevLinkUp) {
-            event = NS_NETWORK_LINK_DATA_UP;
-        } else {
-            // Known status and it was already UP
-            event = nullptr;
-        }
-
-        if (event) {
-            SendEvent(event);
-        }
     } else {
         ret = CheckAdaptersAddresses();
         if (ret != ERROR_SUCCESS) {
             mLinkUp = true;
         }
-
-        if (mLinkUp && (prevCsum != mIPInterfaceChecksum)) {
-            TimeDuration since = TimeStamp::Now() - mChangedTime;
+    }
 
-            // Network is online. Topology has changed. Always send CHANGED
-            // before UP - after having cooled down.
-            if (since.ToMilliseconds() > 2000) {
-                SendEvent(NS_NETWORK_LINK_DATA_CHANGED);
-            }
-        }
-        if (prevLinkUp != mLinkUp) {
-            // UP/DOWN status changed, send appropriate UP/DOWN event
-            SendEvent(mLinkUp ?
-                      NS_NETWORK_LINK_DATA_UP : NS_NETWORK_LINK_DATA_DOWN);
-        }
-    }
+    if (mStatusKnown)
+        event = mLinkUp ? NS_NETWORK_LINK_DATA_UP : NS_NETWORK_LINK_DATA_DOWN;
+    else
+        event = NS_NETWORK_LINK_DATA_UNKNOWN;
+    SendEventToUI(event);
 }
--- a/netwerk/system/win32/nsNotifyAddrListener.h
+++ b/netwerk/system/win32/nsNotifyAddrListener.h
@@ -9,34 +9,32 @@
 #include <windows.h>
 #include <winsock2.h>
 #include <iptypes.h>
 #include "nsINetworkLinkService.h"
 #include "nsIRunnable.h"
 #include "nsIObserver.h"
 #include "nsThreadUtils.h"
 #include "nsCOMPtr.h"
-#include "mozilla/TimeStamp.h"
 
 class nsNotifyAddrListener : public nsINetworkLinkService,
                              public nsIRunnable,
                              public nsIObserver
 {
     virtual ~nsNotifyAddrListener();
 
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSINETWORKLINKSERVICE
     NS_DECL_NSIRUNNABLE
     NS_DECL_NSIOBSERVER
 
     nsNotifyAddrListener();
 
     nsresult Init(void);
-    void CheckLinkStatus(void);
 
 protected:
     class ChangeEvent : public nsRunnable {
     public:
         NS_DECL_NSIRUNNABLE
         ChangeEvent(nsINetworkLinkService *aService, const char *aEventID)
             : mService(aService), mEventID(aEventID) {
         }
@@ -45,30 +43,21 @@ protected:
         const char *mEventID;
     };
 
     bool mLinkUp;
     bool mStatusKnown;
     bool mCheckAttempted;
 
     nsresult Shutdown(void);
-    nsresult SendEvent(const char *aEventID);
+    nsresult SendEventToUI(const char *aEventID);
 
     DWORD CheckAdaptersAddresses(void);
-
-    // Checks for an Internet Connection Sharing (ICS) gateway.
-    bool  CheckICSGateway(PIP_ADAPTER_ADDRESSES aAdapter);
+    bool  CheckIsGateway(PIP_ADAPTER_ADDRESSES aAdapter);
     bool  CheckICSStatus(PWCHAR aAdapterName);
+    void  CheckLinkStatus(void);
 
     nsCOMPtr<nsIThread> mThread;
 
     HANDLE        mShutdownEvent;
-
-private:
-    // This is a checksum of various meta data for all network interfaces
-    // considered UP at last check.
-    ULONG mIPInterfaceChecksum;
-
-    // time of the last sent changed event
-    mozilla::TimeStamp mChangedTime;
 };
 
 #endif /* NSNOTIFYADDRLISTENER_H_ */