diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 6a654ba472b..9395f702906 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1017,6 +1017,10 @@ pref("security.fileuri.strict_origin_policy", true); // the results pref("network.allow-experiments", true); +// Allow the network changed event to get sent when a network topology or +// setup change is noticed while running. +pref("network.notify.changed", true); + // Transmit UDP busy-work to the LAN when anticipating low latency // network reads and on wifi to mitigate 802.11 Power Save Polling delays pref("network.tickle-wifi.enabled", false); diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp index 8d7f356ed73..cf14f28ae15 100644 --- a/netwerk/base/src/nsIOService.cpp +++ b/netwerk/base/src/nsIOService.cpp @@ -55,6 +55,7 @@ using namespace mozilla; // but the old names are still used to preserve backward compatibility. #define NECKO_BUFFER_CACHE_COUNT_PREF "network.buffer.cache.count" #define NECKO_BUFFER_CACHE_SIZE_PREF "network.buffer.cache.size" +#define NETWORK_NOTIFY_CHANGED_PREF "network.notify.changed" #define MAX_RECURSION_COUNT 50 @@ -149,6 +150,7 @@ nsIOService::nsIOService() , mNetworkLinkServiceInitialized(false) , mChannelEventSinks(NS_CHANNEL_EVENT_SINK_CATEGORY) , mAutoDialEnabled(false) + , mNetworkNotifyChanged(true) { } @@ -188,6 +190,7 @@ nsIOService::Init() prefBranch->AddObserver(MANAGE_OFFLINE_STATUS_PREF, this, true); prefBranch->AddObserver(NECKO_BUFFER_CACHE_COUNT_PREF, this, true); prefBranch->AddObserver(NECKO_BUFFER_CACHE_SIZE_PREF, this, true); + prefBranch->AddObserver(NETWORK_NOTIFY_CHANGED_PREF, this, true); PrefsChanged(prefBranch); } @@ -852,6 +855,14 @@ nsIOService::PrefsChanged(nsIPrefBranch *prefs, const char *pref) gDefaultSegmentSize = size; NS_WARN_IF_FALSE( (!(size & (size - 1))) , "network segment size is not a power of 2!"); } + + if (!pref || strcmp(pref, NETWORK_NOTIFY_CHANGED_PREF) == 0) { + bool allow; + nsresult rv = prefs->GetBoolPref(NETWORK_NOTIFY_CHANGED_PREF, &allow); + if (NS_SUCCEEDED(rv)) { + mNetworkNotifyChanged = allow; + } + } } void @@ -958,7 +969,7 @@ nsIOService::Observe(nsISupports *subject, NS_ASSERTION(observerService, "The observer service should not be null"); - if (observerService) { + if (observerService && mNetworkNotifyChanged) { (void)observerService-> NotifyObservers(nullptr, NS_NETWORK_LINK_TOPIC, diff --git a/netwerk/base/src/nsIOService.h b/netwerk/base/src/nsIOService.h index f442fb52a20..2839d9b057d 100644 --- a/netwerk/base/src/nsIOService.h +++ b/netwerk/base/src/nsIOService.h @@ -129,6 +129,7 @@ private: nsTArray mRestrictedPortList; bool mAutoDialEnabled; + bool mNetworkNotifyChanged; public: // Used for all default buffer sizes that necko allocates. static uint32_t gDefaultSegmentSize; diff --git a/netwerk/system/win32/nsNotifyAddrListener.cpp b/netwerk/system/win32/nsNotifyAddrListener.cpp index 8d57fa6c16b..e97174a5479 100644 --- a/netwerk/system/win32/nsNotifyAddrListener.cpp +++ b/netwerk/system/win32/nsNotifyAddrListener.cpp @@ -27,10 +27,13 @@ #include "nsAutoPtr.h" #include "mozilla/Services.h" #include "nsCRT.h" +#include "mozilla/Preferences.h" #include #include +using namespace mozilla; + static HMODULE sNetshell; static decltype(NcFreeNetconProperties)* sNcFreeNetconProperties; @@ -38,6 +41,8 @@ static HMODULE sIphlpapi; static decltype(NotifyIpInterfaceChange)* sNotifyIpInterfaceChange; static decltype(CancelMibChangeNotify2)* sCancelMibChangeNotify2; +#define NETWORK_NOTIFY_CHANGED_PREF "network.notify.changed" + static void InitIphlpapi(void) { if (!sIphlpapi) { @@ -91,6 +96,7 @@ nsNotifyAddrListener::nsNotifyAddrListener() , mCheckAttempted(false) , mShutdownEvent(nullptr) , mIPInterfaceChecksum(0) + , mAllowChangedEvent(true) { InitIphlpapi(); } @@ -215,6 +221,9 @@ nsNotifyAddrListener::Init(void) false); NS_ENSURE_SUCCESS(rv, rv); + Preferences::AddBoolVarCache(&mAllowChangedEvent, + NETWORK_NOTIFY_CHANGED_PREF, true); + mShutdownEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); NS_ENSURE_TRUE(mShutdownEvent, NS_ERROR_OUT_OF_MEMORY); @@ -500,8 +509,8 @@ nsNotifyAddrListener::CheckLinkStatus(void) TimeDuration since = TimeStamp::Now() - mChangedTime; // Network is online. Topology has changed. Always send CHANGED - // before UP - after having cooled down. - if (since.ToMilliseconds() > 2000) { + // before UP - if allowed to and having cooled down. + if (mAllowChangedEvent && (since.ToMilliseconds() > 2000)) { SendEvent(NS_NETWORK_LINK_DATA_CHANGED); } } diff --git a/netwerk/system/win32/nsNotifyAddrListener.h b/netwerk/system/win32/nsNotifyAddrListener.h index 1c7e13ef350..4a0f383e185 100644 --- a/netwerk/system/win32/nsNotifyAddrListener.h +++ b/netwerk/system/win32/nsNotifyAddrListener.h @@ -69,6 +69,9 @@ private: // time of the last sent changed event mozilla::TimeStamp mChangedTime; + + // Network changed events are enabled + bool mAllowChangedEvent; }; #endif /* NSNOTIFYADDRLISTENER_H_ */ diff --git a/netwerk/test/unit/test_ping_aboutnetworking.js b/netwerk/test/unit/test_ping_aboutnetworking.js index 90313688908..6db46cb933f 100644 --- a/netwerk/test/unit/test_ping_aboutnetworking.js +++ b/netwerk/test/unit/test_ping_aboutnetworking.js @@ -42,6 +42,16 @@ function test_sockets(serverSocket) { } function run_test() { + var ps = Cc["@mozilla.org/preferences-service;1"] + .getService(Ci.nsIPrefBranch); + // disable network changed events to avoid the the risk of having the dns + // cache getting flushed behind our back + ps.setBoolPref("network.notify.changed", false); + + do_register_cleanup(function() { + ps.clearUserPref("network.notify.changed"); + }); + let serverSocket = Components.classes["@mozilla.org/network/server-socket;1"] .createInstance(Ci.nsIServerSocket); serverSocket.init(-1, true, -1);