зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1460537 - Connectivity Service - Add check for IPv4/v6 connectivity r=dragana
This is likely not the best approach to detecting IP connectivity. The check has a slight delay until the failure counter reaches the threshold. A more reliable way will be added in a follow-up. Depends on D7844 Differential Revision: https://phabricator.services.mozilla.com/D8704 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
23793b33e1
Коммит
0774dd10ce
|
@ -6,6 +6,7 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsSocketTransport2.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
@ -64,6 +65,27 @@ NetworkConnectivityService::GetDNSv6(int32_t *aState)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::GetIPv4(int32_t *aState)
|
||||
{
|
||||
NS_ENSURE_ARG(aState);
|
||||
*aState = nsSocketTransport::HasIPv4Connectivity()
|
||||
? nsINetworkConnectivityService::OK
|
||||
: nsINetworkConnectivityService::NOT_AVAILABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::GetIPv6(int32_t *aState)
|
||||
{
|
||||
NS_ENSURE_ARG(aState);
|
||||
*aState = nsSocketTransport::HasIPv6Connectivity()
|
||||
? nsINetworkConnectivityService::OK
|
||||
: nsINetworkConnectivityService::NOT_AVAILABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
NetworkConnectivityService::PerformChecks()
|
||||
{
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
namespace {
|
||||
StaticRefPtr<RedirectChannelRegistrar> gSingleton;
|
||||
}
|
||||
StaticRefPtr<RedirectChannelRegistrar> RedirectChannelRegistrar::gSingleton;
|
||||
|
||||
NS_IMPL_ISUPPORTS(RedirectChannelRegistrar, nsIRedirectChannelRegistrar)
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ protected:
|
|||
ParentChannelHashtable mParentChannels;
|
||||
uint32_t mId;
|
||||
Mutex mLock;
|
||||
|
||||
static StaticRefPtr<RedirectChannelRegistrar> gSingleton;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -22,6 +22,10 @@ interface nsINetworkConnectivityService : nsISupports
|
|||
readonly attribute long DNSv4;
|
||||
readonly attribute long DNSv6;
|
||||
|
||||
/* If connecting to IPv4/v6 works on the current network */
|
||||
readonly attribute long IPv4;
|
||||
readonly attribute long IPv6;
|
||||
|
||||
/* Starts the DNS request to check for DNS v4/v6 availability */
|
||||
void recheckDNS();
|
||||
};
|
||||
|
|
|
@ -755,6 +755,15 @@ nsSocketOutputStream::AsyncWait(nsIOutputStreamCallback *callback,
|
|||
// socket transport impl
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// We assume we have connectivity at first.
|
||||
bool nsSocketTransport::sHasIPv4Connectivity = true;
|
||||
bool nsSocketTransport::sHasIPv6Connectivity = true;
|
||||
|
||||
uint32_t nsSocketTransport::sIPv4FailedCounter = 0;
|
||||
uint32_t nsSocketTransport::sIPv6FailedCounter = 0;
|
||||
|
||||
const uint32_t kFailureThreshold = 50;
|
||||
|
||||
nsSocketTransport::nsSocketTransport()
|
||||
: mTypes(nullptr)
|
||||
, mTypeCount(0)
|
||||
|
@ -1857,14 +1866,25 @@ nsSocketTransport::RecoverFromError()
|
|||
if (NS_SUCCEEDED(mFirstRetryError)) {
|
||||
mFirstRetryError = mCondition;
|
||||
}
|
||||
if ((mState == STATE_CONNECTING) && mDNSRecord &&
|
||||
mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
|
||||
if ((mState == STATE_CONNECTING) && mDNSRecord) {
|
||||
if (mNetAddr.raw.family == AF_INET) {
|
||||
Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
|
||||
UNSUCCESSFUL_CONNECTING_TO_IPV4_ADDRESS);
|
||||
sIPv4FailedCounter++;
|
||||
if (sIPv4FailedCounter > kFailureThreshold) {
|
||||
sHasIPv4Connectivity = false;
|
||||
}
|
||||
if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
|
||||
Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
|
||||
UNSUCCESSFUL_CONNECTING_TO_IPV4_ADDRESS);
|
||||
}
|
||||
} else if (mNetAddr.raw.family == AF_INET6) {
|
||||
Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
|
||||
UNSUCCESSFUL_CONNECTING_TO_IPV6_ADDRESS);
|
||||
sIPv6FailedCounter++;
|
||||
if (sIPv6FailedCounter > kFailureThreshold) {
|
||||
sHasIPv6Connectivity = false;
|
||||
}
|
||||
if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
|
||||
Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
|
||||
UNSUCCESSFUL_CONNECTING_TO_IPV6_ADDRESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2346,12 +2366,18 @@ nsSocketTransport::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
|
|||
//
|
||||
OnSocketConnected();
|
||||
|
||||
if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
|
||||
if (mNetAddr.raw.family == AF_INET) {
|
||||
if (mNetAddr.raw.family == AF_INET) {
|
||||
sIPv4FailedCounter = 0;
|
||||
sHasIPv4Connectivity = true;
|
||||
if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
|
||||
Telemetry::Accumulate(
|
||||
Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
|
||||
SUCCESSFUL_CONNECTING_TO_IPV4_ADDRESS);
|
||||
} else if (mNetAddr.raw.family == AF_INET6) {
|
||||
}
|
||||
} else if (mNetAddr.raw.family == AF_INET6) {
|
||||
sIPv6FailedCounter = 0;
|
||||
sHasIPv6Connectivity = true;
|
||||
if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
|
||||
Telemetry::Accumulate(
|
||||
Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
|
||||
SUCCESSFUL_CONNECTING_TO_IPV6_ADDRESS);
|
||||
|
|
|
@ -177,6 +177,10 @@ public:
|
|||
Telemetry::HistogramID aIDConnectivityChange,
|
||||
Telemetry::HistogramID aIDLinkChange,
|
||||
Telemetry::HistogramID aIDOffline);
|
||||
|
||||
|
||||
static bool HasIPv4Connectivity() { return sHasIPv4Connectivity; }
|
||||
static bool HasIPv6Connectivity() { return sHasIPv6Connectivity; }
|
||||
protected:
|
||||
|
||||
virtual ~nsSocketTransport();
|
||||
|
@ -487,6 +491,11 @@ private:
|
|||
nsresult mFirstRetryError;
|
||||
|
||||
bool mDoNotRetryToConnect;
|
||||
|
||||
static bool sHasIPv4Connectivity;
|
||||
static bool sHasIPv6Connectivity;
|
||||
static uint32_t sIPv4FailedCounter;
|
||||
static uint32_t sIPv6FailedCounter;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -50,4 +50,8 @@ add_task(async function testDNS() {
|
|||
|
||||
equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.OK, "Check DNSv4 support (expect OK)");
|
||||
equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.OK, "Check DNSv6 support (expect OK)");
|
||||
|
||||
// It's difficult to check when there's no connectivity in automation,
|
||||
equal(ncs.IPv4, Ci.nsINetworkConnectivityService.OK, "Check IPv4 support (expect OK)");
|
||||
equal(ncs.IPv6, Ci.nsINetworkConnectivityService.OK, "Check IPv6 support (expect OK)");
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче