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 c9d5d07e1a63
parent 207058 12fcec7a372c
child 207060 4f72287c59ca
push id27544
push userryanvm@gmail.com
push dateWed, 24 Sep 2014 21:10:36 +0000
treeherdermozilla-central@1735ff2bb23e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs939318
milestone35.0a1
backs out89d06d103c10
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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_ */