mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1641222 - Follow CNAME/AliasForm chains r=dragana,necko-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D79264
This commit is contained in:
parent
b1f143193d
commit
da614ff256
@ -832,7 +832,8 @@ nsresult TRR::DohDecode(nsCString& aHost) {
|
||||
}
|
||||
uint16_t TYPE = get16bit(mResponse, index);
|
||||
|
||||
if ((TYPE != TRRTYPE_CNAME) && (TYPE != static_cast<uint16_t>(mType))) {
|
||||
if ((TYPE != TRRTYPE_CNAME) && (TYPE != TRRTYPE_HTTPSSVC) &&
|
||||
(TYPE != static_cast<uint16_t>(mType))) {
|
||||
// Not the same type as was asked for nor CNAME
|
||||
LOG(("TRR: Dohdecode:%d asked for type %d got %d\n", __LINE__, mType,
|
||||
TYPE));
|
||||
@ -1024,6 +1025,24 @@ nsresult TRR::DohDecode(nsCString& aHost) {
|
||||
parsed.mSvcFieldValue.AppendElement(value);
|
||||
}
|
||||
|
||||
// Check for AliasForm
|
||||
if (mCname.IsEmpty() && parsed.mSvcFieldPriority == 0) {
|
||||
// Alias form SvcDomainName must not have the "." value (empty)
|
||||
if (parsed.mSvcDomainName.IsEmpty()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
mCname = parsed.mSvcDomainName;
|
||||
ToLowerCase(mCname);
|
||||
LOG(("TRR::DohDecode HTTPSSVC AliasForm host %s => %s\n",
|
||||
host.get(), mCname.get()));
|
||||
break;
|
||||
}
|
||||
|
||||
if (mType != TRRTYPE_HTTPSSVC) {
|
||||
// Ignore the entry that we just parsed if we didn't ask for it.
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mResult.is<TypeRecordHTTPSSVC>()) {
|
||||
mResult = mozilla::AsVariant(CopyableTArray<SVCB>());
|
||||
}
|
||||
@ -1280,7 +1299,7 @@ nsresult TRR::On200Response(nsIChannel* aChannel) {
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (!mDNS.mAddresses.getFirst() && !mCname.IsEmpty() &&
|
||||
mType != TRRTYPE_TXT && mType != TRRTYPE_HTTPSSVC) {
|
||||
mType != TRRTYPE_TXT) {
|
||||
nsCString cname = mCname;
|
||||
LOG(("TRR: check for CNAME record for %s within previous response\n",
|
||||
cname.get()));
|
||||
|
@ -102,13 +102,17 @@ class TRRDNSListener {
|
||||
const dns = Cc["@mozilla.org/network/dns-service;1"].getService(
|
||||
Ci.nsIDNSService
|
||||
);
|
||||
const threadManager = Cc["@mozilla.org/thread-manager;1"].getService(
|
||||
Ci.nsIThreadManager
|
||||
);
|
||||
const currentThread = threadManager.currentThread;
|
||||
|
||||
if (trrServer == "") {
|
||||
this.request = dns.asyncResolve(
|
||||
name,
|
||||
0,
|
||||
this,
|
||||
Services.tm.currentThread,
|
||||
currentThread,
|
||||
{} // defaultOriginAttributes
|
||||
);
|
||||
} else {
|
||||
@ -118,7 +122,7 @@ class TRRDNSListener {
|
||||
trrServer,
|
||||
0,
|
||||
this,
|
||||
Services.tm.currentThread,
|
||||
currentThread,
|
||||
{} // defaultOriginAttributes
|
||||
);
|
||||
Assert.ok(!expectEarlyFail);
|
||||
|
@ -205,3 +205,230 @@ add_task(async function testHTTPSSVC() {
|
||||
Assert.equal(answer[2].name, "hello");
|
||||
Assert.equal(answer[2].values.length, 0);
|
||||
});
|
||||
|
||||
add_task(async function test_aliasform() {
|
||||
let trrServer = new TRRServer();
|
||||
registerCleanupFunction(async () => trrServer.stop());
|
||||
await trrServer.start();
|
||||
dump(`port = ${trrServer.port}\n`);
|
||||
|
||||
if (inChildProcess()) {
|
||||
do_send_remote_message("mode3-port", trrServer.port);
|
||||
await do_await_remote_message("mode3-port-done");
|
||||
} else {
|
||||
Services.prefs.setIntPref("network.trr.mode", 3);
|
||||
Services.prefs.setCharPref(
|
||||
"network.trr.uri",
|
||||
`https://foo.example.com:${trrServer.port}/dns-query`
|
||||
);
|
||||
}
|
||||
|
||||
// Test that HTTPS priority = 0 (AliasForm) behaves like a CNAME
|
||||
await trrServer.registerDoHAnswers("test.com", "A", [
|
||||
{
|
||||
name: "test.com",
|
||||
ttl: 55,
|
||||
type: "HTTPSSVC",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 0,
|
||||
name: "something.com",
|
||||
values: [],
|
||||
},
|
||||
},
|
||||
]);
|
||||
await trrServer.registerDoHAnswers("something.com", "A", [
|
||||
{
|
||||
name: "something.com",
|
||||
ttl: 55,
|
||||
type: "A",
|
||||
flush: false,
|
||||
data: "1.2.3.4",
|
||||
},
|
||||
]);
|
||||
|
||||
await new TRRDNSListener("test.com", "1.2.3.4");
|
||||
|
||||
// Test a chain of HTTPSSVC AliasForm and CNAMEs
|
||||
await trrServer.registerDoHAnswers("x.com", "A", [
|
||||
{
|
||||
name: "x.com",
|
||||
ttl: 55,
|
||||
type: "HTTPSSVC",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 0,
|
||||
name: "y.com",
|
||||
values: [],
|
||||
},
|
||||
},
|
||||
]);
|
||||
await trrServer.registerDoHAnswers("y.com", "A", [
|
||||
{
|
||||
name: "y.com",
|
||||
type: "CNAME",
|
||||
ttl: 55,
|
||||
class: "IN",
|
||||
flush: false,
|
||||
data: "z.com",
|
||||
},
|
||||
]);
|
||||
await trrServer.registerDoHAnswers("z.com", "A", [
|
||||
{
|
||||
name: "z.com",
|
||||
ttl: 55,
|
||||
type: "HTTPSSVC",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 0,
|
||||
name: "target.com",
|
||||
values: [],
|
||||
},
|
||||
},
|
||||
]);
|
||||
await trrServer.registerDoHAnswers("target.com", "A", [
|
||||
{
|
||||
name: "target.com",
|
||||
ttl: 55,
|
||||
type: "A",
|
||||
flush: false,
|
||||
data: "4.3.2.1",
|
||||
},
|
||||
]);
|
||||
|
||||
await new TRRDNSListener("x.com", "4.3.2.1");
|
||||
|
||||
// We get a ServiceForm instead of a A answer, CNAME or AliasForm
|
||||
await trrServer.registerDoHAnswers("no-ip-host.com", "A", [
|
||||
{
|
||||
name: "no-ip-host.com",
|
||||
ttl: 55,
|
||||
type: "HTTPSSVC",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 1,
|
||||
name: "h3pool",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "no-default-alpn" },
|
||||
{ key: "port", value: 8888 },
|
||||
{ key: "ipv4hint", value: "1.2.3.4" },
|
||||
{ key: "esniconfig", value: "123..." },
|
||||
{ key: "ipv6hint", value: "::1" },
|
||||
],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
let [, , inStatus] = await new TRRDNSListener(
|
||||
"no-ip-host.com",
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
Assert.ok(
|
||||
!Components.isSuccessCode(inStatus),
|
||||
`${inStatus} should be an error code`
|
||||
);
|
||||
|
||||
// Test CNAME/AliasForm loop
|
||||
await trrServer.registerDoHAnswers("loop.com", "A", [
|
||||
{
|
||||
name: "loop.com",
|
||||
type: "CNAME",
|
||||
ttl: 55,
|
||||
class: "IN",
|
||||
flush: false,
|
||||
data: "loop2.com",
|
||||
},
|
||||
]);
|
||||
await trrServer.registerDoHAnswers("loop2.com", "A", [
|
||||
{
|
||||
name: "loop2.com",
|
||||
ttl: 55,
|
||||
type: "HTTPSSVC",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 0,
|
||||
name: "loop.com",
|
||||
values: [],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
[, , inStatus] = await new TRRDNSListener("loop.com", undefined, false);
|
||||
Assert.ok(
|
||||
!Components.isSuccessCode(inStatus),
|
||||
`${inStatus} should be an error code`
|
||||
);
|
||||
|
||||
// Alias form for .
|
||||
await trrServer.registerDoHAnswers("empty.com", "A", [
|
||||
{
|
||||
name: "empty.com",
|
||||
ttl: 55,
|
||||
type: "HTTPSSVC",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 0,
|
||||
name: "", // This is not allowed
|
||||
values: [],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
[, , inStatus] = await new TRRDNSListener("empty.com", undefined, false);
|
||||
Assert.ok(
|
||||
!Components.isSuccessCode(inStatus),
|
||||
`${inStatus} should be an error code`
|
||||
);
|
||||
|
||||
// We should ignore ServiceForm if an AliasForm record is also present
|
||||
await trrServer.registerDoHAnswers("multi.com", "HTTPSSVC", [
|
||||
{
|
||||
name: "multi.com",
|
||||
ttl: 55,
|
||||
type: "HTTPSSVC",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 1,
|
||||
name: "h3pool",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "no-default-alpn" },
|
||||
{ key: "port", value: 8888 },
|
||||
{ key: "ipv4hint", value: "1.2.3.4" },
|
||||
{ key: "esniconfig", value: "123..." },
|
||||
{ key: "ipv6hint", value: "::1" },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multi.com",
|
||||
ttl: 55,
|
||||
type: "HTTPSSVC",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 0,
|
||||
name: "example.com",
|
||||
values: [],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
let listener = new DNSListener();
|
||||
let request = dns.asyncResolveByType(
|
||||
"multi.com",
|
||||
dns.RESOLVE_TYPE_HTTPSSVC,
|
||||
0,
|
||||
listener,
|
||||
mainThread,
|
||||
defaultOriginAttributes
|
||||
);
|
||||
|
||||
let [inRequest, inRecord, inStatus2] = await listener;
|
||||
Assert.equal(inRequest, request, "correct request was used");
|
||||
Assert.ok(
|
||||
!Components.isSuccessCode(inStatus2),
|
||||
`${inStatus2} should be an error code`
|
||||
);
|
||||
});
|
||||
|
@ -431,6 +431,7 @@ skip-if = true || asan || tsan || os == 'win' || os =='android'
|
||||
[test_dns_override.js]
|
||||
[test_no_cookies_after_last_pb_exit.js]
|
||||
[test_trr_httpssvc.js]
|
||||
skip-if = os == "android"
|
||||
[test_trr_case_sensitivity.js]
|
||||
skip-if = os == "android"
|
||||
[test_trr_proxy.js]
|
||||
|
8
netwerk/test/unit_ipc/head_trr_clone.js
Normal file
8
netwerk/test/unit_ipc/head_trr_clone.js
Normal file
@ -0,0 +1,8 @@
|
||||
/* import-globals-from ../unit/head_trr.js */
|
||||
|
||||
var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
var { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
load("../unit/head_trr.js");
|
@ -67,5 +67,15 @@ function run_test() {
|
||||
"network.trr.uri",
|
||||
"https://foo.example.com:" + h2Port + "/httpssvc"
|
||||
);
|
||||
|
||||
do_await_remote_message("mode3-port").then(port => {
|
||||
prefs.setIntPref("network.trr.mode", 3);
|
||||
prefs.setCharPref(
|
||||
"network.trr.uri",
|
||||
`https://foo.example.com:${port}/dns-query`
|
||||
);
|
||||
do_send_remote_message("mode3-port-done");
|
||||
});
|
||||
|
||||
run_test_in_child("../unit/test_trr_httpssvc.js");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
[DEFAULT]
|
||||
head = head_channels_clone.js
|
||||
head = head_channels_clone.js head_trr_clone.js
|
||||
skip-if = toolkit == 'android'
|
||||
support-files =
|
||||
child_channel_id.js
|
||||
@ -38,6 +38,7 @@ support-files =
|
||||
!/netwerk/test/unit/test_trackingProtection_annotateChannels.js
|
||||
!/netwerk/test/unit/test_xmlhttprequest.js
|
||||
!/netwerk/test/unit/head_channels.js
|
||||
!/netwerk/test/unit/head_trr.js
|
||||
!/netwerk/test/unit/head_cache2.js
|
||||
!/netwerk/test/unit/data/image.png
|
||||
!/netwerk/test/unit/data/system_root.lnk
|
||||
@ -111,3 +112,4 @@ skip-if = true
|
||||
[test_httpcancel_wrap.js]
|
||||
[test_esni_dns_fetch_wrap.js]
|
||||
[test_trr_httpssvc_wrap.js]
|
||||
skip-if = os == "android"
|
||||
|
Loading…
Reference in New Issue
Block a user