зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1460537 - Connectivity Service - Add DNSv4 and DNSv6 checks r=dragana
Differential Revision: https://phabricator.services.mozilla.com/D7844 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ec3d261a04
Коммит
3753105b42
|
@ -5433,6 +5433,10 @@ pref("network.captive-portal-service.maxInterval", 1500000); // 25 minutes
|
|||
pref("network.captive-portal-service.backoffFactor", "5.0");
|
||||
pref("network.captive-portal-service.enabled", false);
|
||||
|
||||
pref("network.connectivity-service.enabled", true);
|
||||
pref("network.connectivity-service.DNSv4.domain", "mozilla.org");
|
||||
pref("network.connectivity-service.DNSv6.domain", "mozilla.org");
|
||||
|
||||
// DNS Trusted Recursive Resolver
|
||||
// 0 - default off, 1 - race, 2 TRR first, 3 TRR only, 4 shadow, 5 off by choice
|
||||
pref("network.trr.mode", 0);
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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 "NetworkConnectivityService.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS(NetworkConnectivityService, nsINetworkConnectivityService, nsIObserver, nsIDNSListener)
|
||||
|
||||
static StaticRefPtr<NetworkConnectivityService> gConnService;
|
||||
|
||||
// static
|
||||
already_AddRefed<NetworkConnectivityService>
|
||||
NetworkConnectivityService::GetSingleton()
|
||||
{
|
||||
if (gConnService) {
|
||||
return do_AddRef(gConnService);
|
||||
}
|
||||
|
||||
RefPtr<NetworkConnectivityService> service = new NetworkConnectivityService();
|
||||
service->Init();
|
||||
|
||||
gConnService = service.forget();
|
||||
ClearOnShutdown(&gConnService);
|
||||
return do_AddRef(gConnService);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NetworkConnectivityService::Init()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
observerService->AddObserver(this, "network:captive-portal-connectivity", false);
|
||||
|
||||
// We need to schedule this for a bit later, to avoid a recursive service
|
||||
// initialization.
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(
|
||||
NewRunnableMethod("NetworkConnectivityService::PerformChecks",
|
||||
this,
|
||||
&NetworkConnectivityService::PerformChecks)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::GetDNSv4(int32_t *aState)
|
||||
{
|
||||
NS_ENSURE_ARG(aState);
|
||||
*aState = mDNSv4;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::GetDNSv6(int32_t *aState)
|
||||
{
|
||||
NS_ENSURE_ARG(aState);
|
||||
*aState = mDNSv6;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
NetworkConnectivityService::PerformChecks()
|
||||
{
|
||||
RecheckDNS();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::OnLookupComplete(nsICancelable *aRequest,
|
||||
nsIDNSRecord *aRecord,
|
||||
nsresult aStatus)
|
||||
{
|
||||
int32_t state = aRecord ? nsINetworkConnectivityService::OK
|
||||
: nsINetworkConnectivityService::NOT_AVAILABLE;
|
||||
|
||||
if (aRequest == mDNSv4Request) {
|
||||
mDNSv4 = state;
|
||||
mDNSv4Request = nullptr;
|
||||
} else if (aRequest == mDNSv6Request) {
|
||||
mDNSv6 = state;
|
||||
mDNSv6Request = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::OnLookupByTypeComplete(nsICancelable *aRequest,
|
||||
nsIDNSByTypeRecord *aRes,
|
||||
nsresult aStatus)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::RecheckDNS()
|
||||
{
|
||||
bool enabled = Preferences::GetBool("network.connectivity-service.enabled", false);
|
||||
if (!enabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
|
||||
OriginAttributes attrs;
|
||||
nsAutoCString host;
|
||||
Preferences::GetCString("network.connectivity-service.DNSv4.domain", host);
|
||||
|
||||
rv = dns->AsyncResolveNative(host, nsIDNSService::RESOLVE_DISABLE_IPV6,
|
||||
this, NS_GetCurrentThread(),
|
||||
attrs, getter_AddRefs(mDNSv4Request));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Preferences::GetCString("network.connectivity-service.DNSv6.domain", host);
|
||||
rv = dns->AsyncResolveNative(host, nsIDNSService::RESOLVE_DISABLE_IPV4,
|
||||
this, NS_GetCurrentThread(),
|
||||
attrs, getter_AddRefs(mDNSv6Request));
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::Observe(nsISupports *aSubject,
|
||||
const char * aTopic,
|
||||
const char16_t * aData)
|
||||
{
|
||||
if (!strcmp(aTopic, "network:captive-portal-connectivity")) {
|
||||
// Captive portal is cleared, so we redo the checks.
|
||||
mDNSv4 = nsINetworkConnectivityService::UNKNOWN;
|
||||
mDNSv6 = nsINetworkConnectivityService::UNKNOWN;
|
||||
|
||||
PerformChecks();
|
||||
} else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||
if (mDNSv4Request) {
|
||||
mDNSv4Request->Cancel(NS_ERROR_ABORT);
|
||||
mDNSv4Request = nullptr;
|
||||
}
|
||||
if (mDNSv6Request) {
|
||||
mDNSv6Request->Cancel(NS_ERROR_ABORT);
|
||||
mDNSv6Request = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
observerService->RemoveObserver(this, "network:captive-portal-connectivity");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,47 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#ifndef NetworkConnectivityService_h_
|
||||
#define NetworkConnectivityService_h_
|
||||
|
||||
#include "nsINetworkConnectivityService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class NetworkConnectivityService
|
||||
: public nsINetworkConnectivityService
|
||||
, public nsIObserver
|
||||
, public nsIDNSListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINETWORKCONNECTIVITYSERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIDNSLISTENER
|
||||
|
||||
nsresult Init();
|
||||
static already_AddRefed<NetworkConnectivityService> GetSingleton();
|
||||
|
||||
private:
|
||||
NetworkConnectivityService() = default;
|
||||
virtual ~NetworkConnectivityService() = default;
|
||||
|
||||
// Calls all the check methods
|
||||
void PerformChecks();
|
||||
|
||||
// Will be set to OK if the DNS request returned in IP of this type,
|
||||
// NOT_AVAILABLE if that type of resolution is not available
|
||||
// UNKNOWN if the check wasn't performed
|
||||
int32_t mDNSv4 = nsINetworkConnectivityService::UNKNOWN;
|
||||
int32_t mDNSv6 = nsINetworkConnectivityService::UNKNOWN;
|
||||
|
||||
nsCOMPtr<nsICancelable> mDNSv4Request;
|
||||
nsCOMPtr<nsICancelable> mDNSv6Request;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // NetworkConnectivityService_h_
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "RedirectChannelRegistrar.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
|
|
@ -63,6 +63,7 @@ XPIDL_SOURCES += [
|
|||
'nsINestedURI.idl',
|
||||
'nsINetAddr.idl',
|
||||
'nsINetUtil.idl',
|
||||
'nsINetworkConnectivityService.idl',
|
||||
'nsINetworkInfoService.idl',
|
||||
'nsINetworkInterceptController.idl',
|
||||
'nsINetworkLinkService.idl',
|
||||
|
@ -173,6 +174,7 @@ EXPORTS.mozilla.net += [
|
|||
'DashboardTypes.h',
|
||||
'IOActivityMonitor.h',
|
||||
'MemoryDownloader.h',
|
||||
'NetworkConnectivityService.h',
|
||||
'PartiallySeekableInputStream.h',
|
||||
'Predictor.h',
|
||||
'RedirectChannelRegistrar.h',
|
||||
|
@ -194,6 +196,7 @@ UNIFIED_SOURCES += [
|
|||
'LoadContextInfo.cpp',
|
||||
'LoadInfo.cpp',
|
||||
'MemoryDownloader.cpp',
|
||||
'NetworkConnectivityService.cpp',
|
||||
'nsAsyncRedirectVerifyHelper.cpp',
|
||||
'nsAsyncStreamCopier.cpp',
|
||||
'nsAuthInformationHolder.cpp',
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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"
|
||||
|
||||
[scriptable, builtinclass, uuid(2693457e-3ba5-4455-991f-5350946adb12)]
|
||||
interface nsINetworkConnectivityService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Each tested feature may be in one of 3 states:
|
||||
* UNKNOWN, if a check hasn't been performed.
|
||||
* OK, if the feature was successfully tested
|
||||
* NOT_AVAILABLE, if the feature is blocked by the network.
|
||||
* Note that the endpoints are guaranteed to support the features.
|
||||
*/
|
||||
const long UNKNOWN = 0;
|
||||
const long OK = 1;
|
||||
const long NOT_AVAILABLE = 2;
|
||||
|
||||
/* If DNS v4/v6 queries actually work on the current network */
|
||||
readonly attribute long DNSv4;
|
||||
readonly attribute long DNSv6;
|
||||
|
||||
/* Starts the DNS request to check for DNS v4/v6 availability */
|
||||
void recheckDNS();
|
||||
};
|
|
@ -53,6 +53,7 @@
|
|||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
||||
#include "mozilla/net/CaptivePortalService.h"
|
||||
#include "mozilla/net/NetworkConnectivityService.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "ReferrerPolicy.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
|
@ -262,6 +263,10 @@ nsIOService::Init()
|
|||
|
||||
SetOffline(false);
|
||||
|
||||
RefPtr<NetworkConnectivityService> ncs =
|
||||
NetworkConnectivityService::GetSingleton();
|
||||
ncs->Init();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -452,6 +452,16 @@
|
|||
{ 0x92, 0x05, 0xc3, 0x09, 0xce, 0xb2, 0xd6, 0x41 } \
|
||||
}
|
||||
|
||||
#define NS_NETWORKCONNECTIVITYSERVICE_CONTRACTID \
|
||||
"@mozilla.org/network/network-connectivity-service;1"
|
||||
#define NS_NETWORKCONNECTIVITYSERVICE_CID \
|
||||
{ /* 2693457e-3ba5-4455-991f-5350946adb12 */ \
|
||||
0x2693457e, \
|
||||
0x3ba5, \
|
||||
0x4455, \
|
||||
{ 0x99, 0x1f, 0x53, 0x50, 0x94, 0x6a, 0xdb, 0x12 } \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* netwerk/cache/ classes
|
||||
*/
|
||||
|
|
|
@ -141,6 +141,14 @@ namespace net {
|
|||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#include "mozilla/net/NetworkConnectivityService.h"
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsINetworkConnectivityService,
|
||||
NetworkConnectivityService::GetSingleton)
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern nsresult
|
||||
|
@ -722,6 +730,7 @@ NS_DEFINE_NAMED_CID(NS_CACHE_STORAGE_SERVICE_CID);
|
|||
NS_DEFINE_NAMED_CID(NS_NSILOADCONTEXTINFOFACTORY_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_NETWORKPREDICTOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CAPTIVEPORTAL_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_NETWORKCONNECTIVITYSERVICE_CID);
|
||||
#ifdef BUILD_NETWORK_INFO_SERVICE
|
||||
NS_DEFINE_NAMED_CID(NETWORKINFOSERVICE_CID);
|
||||
#endif // BUILD_NETWORK_INFO_SERVICE
|
||||
|
@ -830,6 +839,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
|
|||
{ &kNS_NSILOADCONTEXTINFOFACTORY_CID, false, nullptr, LoadContextInfoFactoryConstructor },
|
||||
{ &kNS_NETWORKPREDICTOR_CID, false, nullptr, mozilla::net::Predictor::Create },
|
||||
{ &kNS_CAPTIVEPORTAL_CID, false, nullptr, mozilla::net::nsICaptivePortalServiceConstructor },
|
||||
{ &kNS_NETWORKCONNECTIVITYSERVICE_CID, false, nullptr, mozilla::net::nsINetworkConnectivityServiceConstructor },
|
||||
#ifdef BUILD_NETWORK_INFO_SERVICE
|
||||
{ &kNETWORKINFOSERVICE_CID, false, nullptr, nsNetworkInfoServiceConstructor },
|
||||
#endif
|
||||
|
@ -938,6 +948,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
|
|||
{ NS_NSILOADCONTEXTINFOFACTORY_CONTRACTID, &kNS_NSILOADCONTEXTINFOFACTORY_CID },
|
||||
{ NS_NETWORKPREDICTOR_CONTRACTID, &kNS_NETWORKPREDICTOR_CID },
|
||||
{ NS_CAPTIVEPORTAL_CONTRACTID, &kNS_CAPTIVEPORTAL_CID },
|
||||
{ NS_NETWORKCONNECTIVITYSERVICE_CONTRACTID, &kNS_NETWORKCONNECTIVITYSERVICE_CID },
|
||||
#ifdef BUILD_NETWORK_INFO_SERVICE
|
||||
{ NETWORKINFOSERVICE_CONTRACT_ID, &kNETWORKINFOSERVICE_CID },
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("network.connectivity-service.DNSv4.domain");
|
||||
Services.prefs.clearUserPref("network.connectivity-service.DNSv6.domain");
|
||||
});
|
||||
|
||||
const DEFAULT_WAIT_TIME = 200; // ms
|
||||
|
||||
const kDNSv6Domain = (mozinfo.os == "linux")
|
||||
? "ip6-localhost"
|
||||
: "localhost";
|
||||
|
||||
add_task(async function testDNS() {
|
||||
let ncs = Cc["@mozilla.org/network/network-connectivity-service;1"]
|
||||
.getService(Ci.nsINetworkConnectivityService);
|
||||
|
||||
// Set the endpoints, trigger a DNS recheck, and wait for it to complete.
|
||||
Services.prefs.setCharPref("network.connectivity-service.DNSv4.domain", "example.org");
|
||||
Services.prefs.setCharPref("network.connectivity-service.DNSv6.domain", kDNSv6Domain);
|
||||
ncs.recheckDNS();
|
||||
await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
|
||||
|
||||
equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.OK, "Check DNSv4 support (expect OK)");
|
||||
equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.OK, "Check DNSv6 support (expect OK)");
|
||||
|
||||
// Set the endpoints to non-exitant domains, trigger a DNS recheck, and wait for it to complete.
|
||||
Services.prefs.setCharPref("network.connectivity-service.DNSv4.domain", "does-not-exist.example");
|
||||
Services.prefs.setCharPref("network.connectivity-service.DNSv6.domain", "does-not-exist.example");
|
||||
ncs.recheckDNS();
|
||||
await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
|
||||
|
||||
equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.NOT_AVAILABLE, "Check DNSv4 support (expect N/A)");
|
||||
equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.NOT_AVAILABLE, "Check DNSv6 support (expect N/A)");
|
||||
|
||||
// Set the endpoints back to the proper domains, and simulate a captive portal
|
||||
// event.
|
||||
Services.prefs.setCharPref("network.connectivity-service.DNSv4.domain", "example.org");
|
||||
Services.prefs.setCharPref("network.connectivity-service.DNSv6.domain", kDNSv6Domain);
|
||||
Services.obs.notifyObservers(null, "network:captive-portal-connectivity", null);
|
||||
// This will cause the state to go to UNKNOWN for a bit, until the check is completed.
|
||||
equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.UNKNOWN, "Check DNSv4 support (expect UNKNOWN)");
|
||||
equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.UNKNOWN, "Check DNSv6 support (expect UNKNOWN)");
|
||||
|
||||
await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
|
||||
|
||||
equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.OK, "Check DNSv4 support (expect OK)");
|
||||
equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.OK, "Check DNSv6 support (expect OK)");
|
||||
});
|
|
@ -422,3 +422,5 @@ run-sequentially = node server exceptions dont replay well
|
|||
[test_esni_dns_fetch.js]
|
||||
# http2-using tests require node available
|
||||
skip-if = os == "android"
|
||||
[test_network_connectivity_service.js]
|
||||
skip-if = os == "android" # DNSv6 issues on android
|
||||
|
|
Загрузка…
Ссылка в новой задаче