Bug 1810362 - Sort the addresses in a DNS lookup result so the IPv6 ones come first. r=valentin,necko-reviewers,kershaw

Introduce network.dns.preferIPv6 pref to place IPv6 addresses first in a DNS lookup result.

Differential Revision: https://phabricator.services.mozilla.com/D206843
This commit is contained in:
Ser Freeman 2024-04-12 10:39:32 +00:00
parent 83ac77eef5
commit d2b6e6098c
4 changed files with 66 additions and 0 deletions

View file

@ -13156,6 +13156,12 @@
value: false
mirror: always
# Whether to prefer IPv6 name lookups.
- name: network.dns.preferIPv6
type: RelaxedAtomicBool
value: false
mirror: always
# Whether to add additional record IPs to the cache
- name: network.trr.add_additional_records
type: RelaxedAtomicBool

View file

@ -216,6 +216,11 @@ class AddrInfo {
mInfo->mAddresses = std::move(addresses);
}
template <class Comparator>
void SortAddresses(const Comparator& aComp) {
mInfo->mAddresses.Sort(aComp);
}
void SetCanonicalHostname(const nsACString& aCname) {
mInfo->mCanonicalName = aCname;
}

View file

@ -1490,6 +1490,18 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
aReason, aTRRRequest, lock);
}
namespace {
class NetAddrIPv6FirstComparator {
public:
static bool Equals(const NetAddr& aLhs, const NetAddr& aRhs) {
return aLhs.raw.family == aRhs.raw.family;
}
static bool LessThan(const NetAddr& aLhs, const NetAddr& aRhs) {
return aLhs.raw.family > aRhs.raw.family;
}
};
} // namespace
nsHostResolver::LookupStatus nsHostResolver::CompleteLookupLocked(
nsHostRecord* rec, nsresult status, AddrInfo* aNewRRSet, bool pb,
const nsACString& aOriginsuffix, TRRSkippedReason aReason,
@ -1601,6 +1613,16 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookupLocked(
old_addr_info = std::move(newRRSet);
}
addrRec->negative = !addrRec->addr_info;
if (addrRec->addr_info && StaticPrefs::network_dns_preferIPv6() &&
addrRec->addr_info->Addresses().Length() > 1 &&
addrRec->addr_info->Addresses()[0].IsIPAddrV4()) {
// Sort IPv6 addresses first.
auto builder = addrRec->addr_info->Build();
builder.SortAddresses(NetAddrIPv6FirstComparator());
addrRec->addr_info = builder.Finish();
}
PrepareRecordExpirationAddrRecord(addrRec);
}

View file

@ -121,3 +121,36 @@ add_task(
}
}
);
add_task(
{
skip_if: () =>
Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT,
},
async function test_sort_family() {
Services.prefs.setBoolPref("network.dns.preferIPv6", true);
overrideService.clearOverrides();
overrideService.addIPOverride("example.com", "1.2.3.4");
overrideService.addIPOverride("example.com", "3.4.5.6");
overrideService.addIPOverride("example.com", "::1");
overrideService.addIPOverride("example.com", "::2");
let listener = new Listener();
Services.dns.asyncResolve(
"example.com",
Ci.nsIDNSService.RESOLVE_TYPE_DEFAULT,
Ci.nsIDNSService.RESOLVE_CANONICAL_NAME,
null, // resolverInfo
listener,
mainThread,
defaultOriginAttributes
);
let [, inRecord] = await listener;
inRecord.QueryInterface(Ci.nsIDNSAddrRecord);
Assert.equal(inRecord.getNextAddrAsString(), "::1");
Assert.equal(inRecord.getNextAddrAsString(), "::2");
Assert.equal(inRecord.getNextAddrAsString(), "1.2.3.4");
Assert.equal(inRecord.getNextAddrAsString(), "3.4.5.6");
}
);