Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* 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";
let trrServer;
function setup() {
trr_test_setup();
Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
}
setup();
registerCleanupFunction(async () => {
trr_clear_prefs();
Services.prefs.clearUserPref("network.dns.upgrade_with_https_rr");
Services.prefs.clearUserPref("network.dns.use_https_rr_as_altsvc");
Services.prefs.clearUserPref("network.dns.echconfig.enabled");
Services.prefs.clearUserPref("network.dns.http3_echconfig.enabled");
Services.prefs.clearUserPref("network.http.http3.enable");
Services.prefs.clearUserPref("network.http.http2.enabled");
if (trrServer) {
await trrServer.stop();
}
});
function checkResult(inRecord, noHttp2, noHttp3, result) {
if (!result) {
Assert.throws(
() => {
inRecord
.QueryInterface(Ci.nsIDNSHTTPSSVCRecord)
.GetServiceModeRecord(noHttp2, noHttp3);
},
/NS_ERROR_NOT_AVAILABLE/,
"Should get an error"
);
return;
}
let record = inRecord
.QueryInterface(Ci.nsIDNSHTTPSSVCRecord)
.GetServiceModeRecord(noHttp2, noHttp3);
Assert.equal(record.priority, result.expectedPriority);
Assert.equal(record.name, result.expectedName);
Assert.equal(record.selectedAlpn, result.expectedAlpn);
}
// Test configuration:
// There are two records: one has a echConfig and the other doesn't.
// We want to test if the record with echConfig is preferred.
add_task(async function testEchConfigEnabled() {
trrServer = new TRRServer();
await trrServer.start();
Services.prefs.setIntPref("network.trr.mode", 3);
Services.prefs.setCharPref(
"network.trr.uri",
`https://foo.example.com:${trrServer.port()}/dns-query`
);
Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
await trrServer.registerDoHAnswers("test.bar.com", "HTTPS", {
answers: [
{
name: "test.bar.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 1,
name: "test.bar_1.com",
values: [{ key: "alpn", value: ["h3-29"] }],
},
},
{
name: "test.bar.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 2,
name: "test.bar_2.com",
values: [
{ key: "alpn", value: ["h2"] },
{ key: "echconfig", value: "456..." },
],
},
},
],
});
let { inRecord } = await new TRRDNSListener("test.bar.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
});
checkResult(inRecord, false, false, {
expectedPriority: 1,
expectedName: "test.bar_1.com",
expectedAlpn: "h3-29",
});
checkResult(inRecord, false, true, {
expectedPriority: 2,
expectedName: "test.bar_2.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false, {
expectedPriority: 1,
expectedName: "test.bar_1.com",
expectedAlpn: "h3-29",
});
checkResult(inRecord, true, true);
Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
Services.dns.clearCache(true);
({ inRecord } = await new TRRDNSListener("test.bar.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
}));
checkResult(inRecord, false, false, {
expectedPriority: 2,
expectedName: "test.bar_2.com",
expectedAlpn: "h2",
});
checkResult(inRecord, false, true, {
expectedPriority: 2,
expectedName: "test.bar_2.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false, {
expectedPriority: 1,
expectedName: "test.bar_1.com",
expectedAlpn: "h3-29",
});
checkResult(inRecord, true, true);
await trrServer.stop();
trrServer = null;
});
// Test configuration:
// There are two records: both have echConfigs, and only one supports h3.
// This test is about testing which record should we get when
// network.dns.http3_echconfig.enabled is true and false.
// When network.dns.http3_echconfig.enabled is false, we should try to
// connect with h2 and echConfig.
add_task(async function testTwoRecordsHaveEchConfig() {
Services.dns.clearCache(true);
trrServer = new TRRServer();
await trrServer.start();
Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
Services.prefs.setIntPref("network.trr.mode", 3);
Services.prefs.setCharPref(
"network.trr.uri",
`https://foo.example.com:${trrServer.port()}/dns-query`
);
await trrServer.registerDoHAnswers("test.foo.com", "HTTPS", {
answers: [
{
name: "test.foo.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 1,
name: "test.foo_h3.com",
values: [
{ key: "alpn", value: ["h3"] },
{ key: "echconfig", value: "456..." },
],
},
},
{
name: "test.foo.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 2,
name: "test.foo_h2.com",
values: [
{ key: "alpn", value: ["h2"] },
{ key: "echconfig", value: "456..." },
],
},
},
],
});
let { inRecord } = await new TRRDNSListener("test.foo.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
});
checkResult(inRecord, false, false, {
expectedPriority: 2,
expectedName: "test.foo_h2.com",
expectedAlpn: "h2",
});
checkResult(inRecord, false, true, {
expectedPriority: 2,
expectedName: "test.foo_h2.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, true, true);
Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
Services.dns.clearCache(true);
({ inRecord } = await new TRRDNSListener("test.foo.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
}));
checkResult(inRecord, false, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, false, true, {
expectedPriority: 2,
expectedName: "test.foo_h2.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, true, true);
await trrServer.stop();
trrServer = null;
});
// Test configuration:
// There are two records: both have echConfigs, and one supports h3 and h2.
// When network.dns.http3_echconfig.enabled is false, we should use the record
// that supports h3 and h2 (the alpn is h2).
add_task(async function testTwoRecordsHaveEchConfig1() {
Services.dns.clearCache(true);
trrServer = new TRRServer();
await trrServer.start();
Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
Services.prefs.setIntPref("network.trr.mode", 3);
Services.prefs.setCharPref(
"network.trr.uri",
`https://foo.example.com:${trrServer.port()}/dns-query`
);
await trrServer.registerDoHAnswers("test.foo.com", "HTTPS", {
answers: [
{
name: "test.foo.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 1,
name: "test.foo_h3.com",
values: [
{ key: "alpn", value: ["h3", "h2"] },
{ key: "echconfig", value: "456..." },
],
},
},
{
name: "test.foo.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 2,
name: "test.foo_h2.com",
values: [
{ key: "alpn", value: ["h2", "http/1.1"] },
{ key: "echconfig", value: "456..." },
],
},
},
],
});
let { inRecord } = await new TRRDNSListener("test.foo.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
});
checkResult(inRecord, false, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h2",
});
checkResult(inRecord, false, true, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false, {
expectedPriority: 2,
expectedName: "test.foo_h2.com",
expectedAlpn: "http/1.1",
});
checkResult(inRecord, true, true, {
expectedPriority: 2,
expectedName: "test.foo_h2.com",
expectedAlpn: "http/1.1",
});
Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
Services.dns.clearCache(true);
({ inRecord } = await new TRRDNSListener("test.foo.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
}));
checkResult(inRecord, false, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, false, true, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, true, true, {
expectedPriority: 2,
expectedName: "test.foo_h2.com",
expectedAlpn: "http/1.1",
});
await trrServer.stop();
trrServer = null;
});
// Test configuration:
// There are two records: only one support h3 and only one has echConfig.
// This test is about never usng the record without echConfig.
add_task(async function testOneRecordsHasEchConfig() {
Services.dns.clearCache(true);
trrServer = new TRRServer();
await trrServer.start();
Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
Services.prefs.setIntPref("network.trr.mode", 3);
Services.prefs.setCharPref(
"network.trr.uri",
`https://foo.example.com:${trrServer.port()}/dns-query`
);
await trrServer.registerDoHAnswers("test.foo.com", "HTTPS", {
answers: [
{
name: "test.foo.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 1,
name: "test.foo_h3.com",
values: [
{ key: "alpn", value: ["h3"] },
{ key: "echconfig", value: "456..." },
],
},
},
{
name: "test.foo.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 2,
name: "test.foo_h2.com",
values: [{ key: "alpn", value: ["h2"] }],
},
},
],
});
let { inRecord } = await new TRRDNSListener("test.foo.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
});
checkResult(inRecord, false, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, false, true, {
expectedPriority: 2,
expectedName: "test.foo_h2.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, true, true);
Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
Services.dns.clearCache(true);
({ inRecord } = await new TRRDNSListener("test.foo.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
}));
checkResult(inRecord, false, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, false, true, {
expectedPriority: 2,
expectedName: "test.foo_h2.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, true, true);
await trrServer.stop();
trrServer = null;
});
// Test the case that "network.http.http3.enable" and
// "network.http.http2.enabled" are true/false.
add_task(async function testHttp3AndHttp2Pref() {
Services.dns.clearCache(true);
trrServer = new TRRServer();
await trrServer.start();
Services.prefs.setBoolPref("network.http.http3.enable", false);
Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
Services.prefs.setIntPref("network.trr.mode", 3);
Services.prefs.setCharPref(
"network.trr.uri",
`https://foo.example.com:${trrServer.port()}/dns-query`
);
await trrServer.registerDoHAnswers("test.foo.com", "HTTPS", {
answers: [
{
name: "test.foo.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 1,
name: "test.foo_h3.com",
values: [
{ key: "alpn", value: ["h3", "h2"] },
{ key: "echconfig", value: "456..." },
],
},
},
{
name: "test.foo.com",
ttl: 55,
type: "HTTPS",
flush: false,
data: {
priority: 2,
name: "test.foo_h2.com",
values: [
{ key: "alpn", value: ["h2"] },
{ key: "echconfig", value: "456..." },
],
},
},
],
});
let { inRecord } = await new TRRDNSListener("test.foo.com", {
type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
});
checkResult(inRecord, false, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h2",
});
checkResult(inRecord, false, true, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h2",
});
checkResult(inRecord, true, false);
checkResult(inRecord, true, true);
Services.prefs.setBoolPref("network.http.http2.enabled", false);
checkResult(inRecord, false, false);
Services.prefs.setBoolPref("network.http.http3.enable", true);
checkResult(inRecord, false, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, false, true);
checkResult(inRecord, true, false, {
expectedPriority: 1,
expectedName: "test.foo_h3.com",
expectedAlpn: "h3",
});
checkResult(inRecord, true, true);
await trrServer.stop();
trrServer = null;
});