Backed out changeset 7f4e096d1be6 (bug 1589781) for NetworkConnectivityService tsan failures CLOSED TREE

This commit is contained in:
Bogdan Tara 2020-09-17 19:28:43 +03:00
Родитель fbca2b9d14
Коммит 8fe09fb514
7 изменённых файлов: 2 добавлений и 243 удалений

Просмотреть файл

@ -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]