зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 7f4e096d1be6 (bug 1589781) for NetworkConnectivityService tsan failures CLOSED TREE
This commit is contained in:
Родитель
fbca2b9d14
Коммит
8fe09fb514
|
@ -8493,12 +8493,6 @@
|
|||
value: false
|
||||
mirror: always
|
||||
|
||||
# Whether to check for NAT64 using the system resolver
|
||||
- name: network.connectivity-service.nat64-check
|
||||
type: bool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Prefs starting with "nglayout."
|
||||
#---------------------------------------------------------------------------
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "xpcpublic.h"
|
||||
#include "nsSocketTransport2.h"
|
||||
#include "nsINetworkLinkService.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
|
||||
static LazyLogModule gNCSLog("NetworkConnectivityService");
|
||||
#undef LOG
|
||||
|
@ -22,9 +21,6 @@ NS_IMPL_ISUPPORTS(NetworkConnectivityService, nsIDNSListener, nsIObserver,
|
|||
|
||||
static StaticRefPtr<NetworkConnectivityService> gConnService;
|
||||
|
||||
NetworkConnectivityService::NetworkConnectivityService()
|
||||
: mLock("nat64prefixes") {}
|
||||
|
||||
// static
|
||||
already_AddRefed<NetworkConnectivityService>
|
||||
NetworkConnectivityService::GetSingleton() {
|
||||
|
@ -83,43 +79,9 @@ NetworkConnectivityService::GetIPv6(ConnectivityState* aState) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::GetNAT64(ConnectivityState* aState) {
|
||||
NS_ENSURE_ARG(aState);
|
||||
*aState = mNAT64;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<AddrInfo> NetworkConnectivityService::MapNAT64IPs(
|
||||
AddrInfo* aNewRRSet) {
|
||||
// This should be called only if there are no IPv6 addresses.
|
||||
|
||||
// Currently we only add prefixes to the first IP's clones.
|
||||
uint32_t ip = aNewRRSet->Addresses()[0].inet.ip;
|
||||
nsTArray<NetAddr> addresses = aNewRRSet->Addresses().Clone();
|
||||
|
||||
MutexAutoLock lock(mLock);
|
||||
size_t prefix_count = mNAT64Prefixes.Length();
|
||||
for (size_t i = 0; i < prefix_count; i++) {
|
||||
NetAddr addr = NetAddr(mNAT64Prefixes[i]);
|
||||
|
||||
// Copy the IPv4 address to the end
|
||||
addr.inet6.ip.u32[3] = ip;
|
||||
|
||||
// If we have both IPv4 and NAT64, we be could insourcing NAT64
|
||||
// to avoid double NAT and improve performance. However, this
|
||||
// breaks WebRTC, so we push it to the back.
|
||||
addresses.AppendElement(addr);
|
||||
}
|
||||
auto builder = aNewRRSet->Build();
|
||||
builder.SetAddresses(std::move(addresses));
|
||||
return builder.Finish();
|
||||
}
|
||||
|
||||
void NetworkConnectivityService::PerformChecks() {
|
||||
mDNSv4 = UNKNOWN;
|
||||
mDNSv6 = UNKNOWN;
|
||||
mNAT64 = UNKNOWN;
|
||||
|
||||
mIPv4 = UNKNOWN;
|
||||
mIPv6 = UNKNOWN;
|
||||
|
@ -133,64 +95,6 @@ static inline void NotifyObservers(const char* aTopic) {
|
|||
obs->NotifyObservers(nullptr, aTopic, nullptr);
|
||||
}
|
||||
|
||||
void NetworkConnectivityService::SaveNAT64Prefixes(nsIDNSRecord* aRecord) {
|
||||
nsCOMPtr<nsIDNSAddrRecord> rec = do_QueryInterface(aRecord);
|
||||
if (!rec) {
|
||||
mNAT64 = UNKNOWN;
|
||||
return;
|
||||
}
|
||||
MutexAutoLock lock(mLock);
|
||||
mNAT64 = OK;
|
||||
mNAT64Prefixes.Clear();
|
||||
NetAddr addr{};
|
||||
// use port 80 as dummy value for NetAddr
|
||||
while (NS_SUCCEEDED(rec->GetNextAddr(80, &addr))) {
|
||||
if (addr.raw.family != AF_INET6 || addr.IsIPAddrV4Mapped()) {
|
||||
mNAT64Prefixes.Clear();
|
||||
mNAT64 = NOT_AVAILABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
// RFC 7050 does not require the embedded IPv4 to be
|
||||
// at the end of IPv6. In practice, and as we assume, it is.
|
||||
// The embedded IP must be 192.0.0.170 or 192.0.0.171
|
||||
|
||||
// Clear the last bit to compare with the next one.
|
||||
addr.inet6.ip.u8[15] &= ~(uint32_t)1;
|
||||
if ((addr.inet6.ip.u8[12] != 192) || (addr.inet6.ip.u8[13] != 0) ||
|
||||
(addr.inet6.ip.u8[14] != 0) || (addr.inet6.ip.u8[15] != 170)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mNAT64Prefixes.AppendElement(addr);
|
||||
}
|
||||
|
||||
if (mNAT64Prefixes.IsEmpty()) {
|
||||
mNAT64 = NOT_AVAILABLE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove duplicates. Typically a DNS64 resolver sends every
|
||||
// prefix twice with address with different last bits. We want
|
||||
// a list of unique prefixes while reordering is not allowed.
|
||||
// We must not handle the case with an element in-between
|
||||
// two identical ones, which is never the case for a properly
|
||||
// configured DNS64 resolver.
|
||||
|
||||
size_t length = mNAT64Prefixes.Length();
|
||||
NetAddr prev = mNAT64Prefixes[0];
|
||||
|
||||
for (size_t i = 1; i < length; i++) {
|
||||
if (mNAT64Prefixes[i] == prev) {
|
||||
mNAT64Prefixes.RemoveElementAt(i);
|
||||
i--;
|
||||
length--;
|
||||
} else {
|
||||
prev = mNAT64Prefixes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NetworkConnectivityService::OnLookupComplete(nsICancelable* aRequest,
|
||||
nsIDNSRecord* aRecord,
|
||||
|
@ -203,12 +107,9 @@ NetworkConnectivityService::OnLookupComplete(nsICancelable* aRequest,
|
|||
} else if (aRequest == mDNSv6Request) {
|
||||
mDNSv6 = state;
|
||||
mDNSv6Request = nullptr;
|
||||
} else if (aRequest == mNAT64Request) {
|
||||
mNAT64Request = nullptr;
|
||||
SaveNAT64Prefixes(aRecord);
|
||||
}
|
||||
|
||||
if (!mDNSv4Request && !mDNSv6Request && !mNAT64Request) {
|
||||
if (!mDNSv4Request && !mDNSv6Request) {
|
||||
NotifyObservers("network:connectivity-service:dns-checks-complete");
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -241,15 +142,6 @@ NetworkConnectivityService::RecheckDNS() {
|
|||
nsIDNSService::RESOLVE_DISABLE_IPV4 | nsIDNSService::RESOLVE_DISABLE_TRR,
|
||||
nullptr, this, NS_GetCurrentThread(), attrs,
|
||||
getter_AddRefs(mDNSv6Request));
|
||||
|
||||
if (StaticPrefs::network_connectivity_service_nat64_check()) {
|
||||
rv = dns->AsyncResolveNative("ipv4only.arpa"_ns,
|
||||
nsIDNSService::RESOLVE_TYPE_DEFAULT,
|
||||
nsIDNSService::RESOLVE_DISABLE_IPV4 |
|
||||
nsIDNSService::RESOLVE_DISABLE_TRR,
|
||||
nullptr, this, NS_GetCurrentThread(), attrs,
|
||||
getter_AddRefs(mNAT64Request));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -268,10 +160,6 @@ NetworkConnectivityService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
mDNSv6Request->Cancel(NS_ERROR_ABORT);
|
||||
mDNSv6Request = nullptr;
|
||||
}
|
||||
if (mNAT64Request) {
|
||||
mNAT64Request->Cancel(NS_ERROR_ABORT);
|
||||
mNAT64Request = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "nsIObserver.h"
|
||||
#include "nsIDNSListener.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
@ -26,43 +25,33 @@ class NetworkConnectivityService : public nsINetworkConnectivityService,
|
|||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
already_AddRefed<AddrInfo> MapNAT64IPs(AddrInfo* aNewRRSet);
|
||||
|
||||
static already_AddRefed<NetworkConnectivityService> GetSingleton();
|
||||
|
||||
private:
|
||||
NetworkConnectivityService();
|
||||
NetworkConnectivityService() = default;
|
||||
virtual ~NetworkConnectivityService() = default;
|
||||
|
||||
nsresult Init();
|
||||
// Calls all the check methods
|
||||
void PerformChecks();
|
||||
|
||||
void SaveNAT64Prefixes(nsIDNSRecord* aRecord);
|
||||
|
||||
// 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
|
||||
ConnectivityState mDNSv4 = nsINetworkConnectivityService::UNKNOWN;
|
||||
ConnectivityState mDNSv6 = nsINetworkConnectivityService::UNKNOWN;
|
||||
ConnectivityState mNAT64 = nsINetworkConnectivityService::UNKNOWN;
|
||||
|
||||
ConnectivityState mIPv4 = nsINetworkConnectivityService::UNKNOWN;
|
||||
ConnectivityState mIPv6 = nsINetworkConnectivityService::UNKNOWN;
|
||||
|
||||
nsTArray<NetAddr> mNAT64Prefixes;
|
||||
|
||||
nsCOMPtr<nsICancelable> mDNSv4Request;
|
||||
nsCOMPtr<nsICancelable> mDNSv6Request;
|
||||
nsCOMPtr<nsICancelable> mNAT64Request;
|
||||
|
||||
nsCOMPtr<nsIChannel> mIPv4Channel;
|
||||
nsCOMPtr<nsIChannel> mIPv6Channel;
|
||||
|
||||
bool mCheckedNetworkId = false;
|
||||
bool mHasNetworkId = false;
|
||||
|
||||
Mutex mLock;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -25,8 +25,6 @@ interface nsINetworkConnectivityService : nsISupports
|
|||
readonly attribute nsINetworkConnectivityService_ConnectivityState DNSv4;
|
||||
[infallible]
|
||||
readonly attribute nsINetworkConnectivityService_ConnectivityState DNSv6;
|
||||
[infallible]
|
||||
readonly attribute nsINetworkConnectivityService_ConnectivityState NAT64;
|
||||
|
||||
/* If connecting to IPv4/v6 works on the current network */
|
||||
[infallible]
|
||||
|
|
|
@ -2048,13 +2048,6 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
|
|||
return LOOKUP_OK;
|
||||
}
|
||||
|
||||
if (addrRec->mTRRSuccess && mNCS &&
|
||||
(mNCS->GetNAT64() == nsINetworkConnectivityService::OK) && newRRSet &&
|
||||
!newRRSet->Addresses().IsEmpty() &&
|
||||
newRRSet->Addresses()[0].raw.family != PR_AF_INET6) {
|
||||
newRRSet = mNCS->MapNAT64IPs(newRRSet);
|
||||
}
|
||||
|
||||
// continue
|
||||
}
|
||||
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const override = Cc["@mozilla.org/network/native-dns-override;1"].getService(
|
||||
Ci.nsINativeDNSResolverOverride
|
||||
);
|
||||
const dns = Cc["@mozilla.org/network/dns-service;1"].getService(
|
||||
Ci.nsIDNSService
|
||||
);
|
||||
|
||||
trr_test_setup();
|
||||
registerCleanupFunction(async () => {
|
||||
trr_clear_prefs();
|
||||
});
|
||||
|
||||
/**
|
||||
* Waits for an observer notification to fire.
|
||||
*
|
||||
* @param {String} topic The notification topic.
|
||||
* @returns {Promise} A promise that fulfills when the notification is fired.
|
||||
*/
|
||||
function promiseObserverNotification(topic, matchFunc) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Services.obs.addObserver(function observe(subject, topic, data) {
|
||||
let matches = typeof matchFunc != "function" || matchFunc(subject, data);
|
||||
if (!matches) {
|
||||
return;
|
||||
}
|
||||
Services.obs.removeObserver(observe, topic);
|
||||
resolve({ subject, data });
|
||||
}, topic);
|
||||
});
|
||||
}
|
||||
|
||||
function makeChan(url) {
|
||||
let chan = NetUtil.newChannel({
|
||||
uri: url,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
return chan;
|
||||
}
|
||||
|
||||
let processId;
|
||||
|
||||
function channelOpenPromise(chan) {
|
||||
return new Promise(resolve => {
|
||||
function finish(req, buffer) {
|
||||
resolve([req, buffer]);
|
||||
}
|
||||
chan.asyncOpen(new ChannelListener(finish));
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function test_add_nat64_prefix_to_trr() {
|
||||
let trrServer = new TRRServer();
|
||||
registerCleanupFunction(async () => trrServer.stop());
|
||||
await trrServer.start();
|
||||
dump(`port = ${trrServer.port}\n`);
|
||||
let chan = makeChan(`https://localhost:${trrServer.port}/test?bla=some`);
|
||||
let [req, resp] = await channelOpenPromise(chan);
|
||||
equal(resp, "<h1> 404 Path not found: /test?bla=some</h1>");
|
||||
dns.clearCache(true);
|
||||
override.addIPOverride("ipv4only.arpa", "fe80::6a99:9b2b:c000:00aa");
|
||||
|
||||
Services.obs.notifyObservers(null, "network:captive-portal-connectivity");
|
||||
await promiseObserverNotification(
|
||||
"network:connectivity-service:dns-checks-complete"
|
||||
);
|
||||
|
||||
Services.prefs.setIntPref("network.trr.mode", 2);
|
||||
Services.prefs.setCharPref(
|
||||
"network.trr.uri",
|
||||
`https://foo.example.com:${trrServer.port}/dns-query`
|
||||
);
|
||||
|
||||
await trrServer.registerDoHAnswers("xyz.foo", "A", [
|
||||
{
|
||||
name: "xyz.foo",
|
||||
ttl: 55,
|
||||
type: "A",
|
||||
flush: false,
|
||||
data: "1.2.3.4",
|
||||
},
|
||||
]);
|
||||
let [, inRecord] = await new TRRDNSListener("xyz.foo", undefined, false);
|
||||
|
||||
inRecord.QueryInterface(Ci.nsIDNSAddrRecord);
|
||||
inRecord.getNextAddrAsString();
|
||||
Assert.equal(
|
||||
inRecord.getNextAddrAsString(),
|
||||
"fe80::6a99:9b2b:102:304",
|
||||
`Checking that the NAT64-prefixed address is appended at the back.`
|
||||
);
|
||||
|
||||
await trrServer.stop();
|
||||
|
||||
override.clearOverrides();
|
||||
});
|
|
@ -23,8 +23,6 @@ support-files =
|
|||
../../dns/effective_tld_names.dat
|
||||
test_alt-data_cross_process.js
|
||||
|
||||
[test_trr_nat64.js]
|
||||
skip-if = os == "android" || socketprocess_networking
|
||||
[test_nsIBufferedOutputStream_writeFrom_block.js]
|
||||
[test_cache2-00-service-get.js]
|
||||
[test_cache2-01-basic.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче