diff options
Diffstat (limited to 'netwerk/test/unit/test_odoh.js')
-rw-r--r-- | netwerk/test/unit/test_odoh.js | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_odoh.js b/netwerk/test/unit/test_odoh.js new file mode 100644 index 0000000000..959b40bb84 --- /dev/null +++ b/netwerk/test/unit/test_odoh.js @@ -0,0 +1,296 @@ +/* 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/. */ + +/* + * Most of tests in this file are reused from test_trr.js, except tests listed + * below. Since ODoH doesn't support push and customerized DNS resolver, some + * related tests are skipped. + * + * test_trr_flags + * test_push + * test_clearCacheOnURIChange // TODO: Clear DNS cache when ODoH prefs changed. + * test_dnsSuffix + * test_async_resolve_with_trr_server + * test_content_encoding_gzip + * test_redirect + * test_confirmation + * test_detected_uri + * test_pref_changes + * test_dohrollout_mode + * test_purge_trr_cache_on_mode_change + * test_old_bootstrap_pref + */ + +"use strict"; + +/* import-globals-from trr_common.js */ + +ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); + +const certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" +].getService(Ci.nsICertOverrideService); + +add_setup(async function setup() { + h2Port = trr_test_setup(); + runningODoHTests = true; + + // This is for skiping the security check for the odoh host. + certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData( + true + ); + + registerCleanupFunction(() => { + trr_clear_prefs(); + Services.prefs.clearUserPref("network.trr.odoh.enabled"); + Services.prefs.clearUserPref("network.trr.odoh.target_path"); + Services.prefs.clearUserPref("network.trr.odoh.configs_uri"); + certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData( + false + ); + }); + + if (mozinfo.socketprocess_networking) { + Services.dns; // Needed to trigger socket process. + await TestUtils.waitForCondition(() => Services.io.socketProcessLaunched); + } + + Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRONLY); +}); + +add_task(async function testODoHConfig() { + // use the h2 server as DOH provider + Services.prefs.setCharPref( + "network.trr.uri", + "https://foo.example.com:" + h2Port + "/odohconfig" + ); + + let { inRecord } = await new TRRDNSListener("odoh_host.example.com", { + type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC, + }); + let answer = inRecord.QueryInterface(Ci.nsIDNSHTTPSSVCRecord).records; + Assert.equal(answer[0].priority, 1); + Assert.equal(answer[0].name, "odoh_host.example.com"); + Assert.equal(answer[0].values.length, 1); + let odohconfig = answer[0].values[0].QueryInterface(Ci.nsISVCParamODoHConfig) + .ODoHConfig; + Assert.equal(odohconfig.length, 46); +}); + +let testIndex = 0; + +async function ODoHConfigTest(query, ODoHHost, expectedResult = false) { + Services.prefs.setCharPref( + "network.trr.uri", + "https://foo.example.com:" + h2Port + "/odohconfig?" + query + ); + + // Setting the pref "network.trr.odoh.target_host" will trigger the reload of + // the ODoHConfigs. + if (ODoHHost != undefined) { + Services.prefs.setCharPref("network.trr.odoh.target_host", ODoHHost); + } else { + Services.prefs.setCharPref( + "network.trr.odoh.target_host", + `https://odoh_host_${testIndex++}.com` + ); + } + + await topicObserved("odoh-service-activated"); + Assert.equal(Services.dns.ODoHActivated, expectedResult); +} + +add_task(async function testODoHConfig1() { + await ODoHConfigTest("invalid=empty"); +}); + +add_task(async function testODoHConfig2() { + await ODoHConfigTest("invalid=version"); +}); + +add_task(async function testODoHConfig3() { + await ODoHConfigTest("invalid=configLength"); +}); + +add_task(async function testODoHConfig4() { + await ODoHConfigTest("invalid=totalLength"); +}); + +add_task(async function testODoHConfig5() { + await ODoHConfigTest("invalid=kemId"); +}); + +add_task(async function testODoHConfig6() { + // Use a very short TTL. + Services.prefs.setIntPref("network.trr.odoh.min_ttl", 1); + await ODoHConfigTest("invalid=kemId&ttl=1"); + + // This is triggered by the expiration of the TTL. + await topicObserved("odoh-service-activated"); + Assert.ok(!Services.dns.ODoHActivated); + Services.prefs.clearUserPref("network.trr.odoh.min_ttl"); +}); + +add_task(async function testODoHConfig7() { + Services.dns.clearCache(true); + Services.prefs.setIntPref("network.trr.mode", 2); // TRR-first + Services.prefs.setBoolPref("network.trr.odoh.enabled", true); + // At this point, we've queried the ODoHConfig, but there is no usable config + // (kemId is not supported). So, we should see the DNS result is from the + // native resolver. + await new TRRDNSListener("bar.example.com", "127.0.0.1"); +}); + +async function ODoHConfigTestHTTP(configUri, expectedResult) { + // Setting the pref "network.trr.odoh.configs_uri" will trigger the reload of + // the ODoHConfigs. + Services.prefs.setCharPref("network.trr.odoh.configs_uri", configUri); + + await topicObserved("odoh-service-activated"); + Assert.equal(Services.dns.ODoHActivated, expectedResult); +} + +add_task(async function testODoHConfig8() { + Services.dns.clearCache(true); + Services.prefs.setCharPref("network.trr.uri", ""); + + await ODoHConfigTestHTTP( + `https://foo.example.com:${h2Port}/odohconfig?downloadFrom=http`, + true + ); +}); + +add_task(async function testODoHConfig9() { + // Reset the prefs back to the correct values, so we will get valid + // ODoHConfigs when "network.trr.odoh.configs_uri" is cleared below. + Services.prefs.setCharPref( + "network.trr.uri", + `https://foo.example.com:${h2Port}/odohconfig` + ); + Services.prefs.setCharPref( + "network.trr.odoh.target_host", + `https://odoh_host.example.com:${h2Port}` + ); + + // Use a very short TTL. + Services.prefs.setIntPref("network.trr.odoh.min_ttl", 1); + // This will trigger to download ODoHConfigs from HTTPS RR. + Services.prefs.clearUserPref("network.trr.odoh.configs_uri"); + + await topicObserved("odoh-service-activated"); + Assert.ok(Services.dns.ODoHActivated); + + await ODoHConfigTestHTTP( + `https://foo.example.com:${h2Port}/odohconfig?downloadFrom=http`, + true + ); + + // This is triggered by the expiration of the TTL. + await topicObserved("odoh-service-activated"); + Assert.ok(Services.dns.ODoHActivated); + Services.prefs.clearUserPref("network.trr.odoh.min_ttl"); +}); + +add_task(async function testODoHConfig10() { + // We can still get ODoHConfigs from HTTPS RR. + await ODoHConfigTestHTTP("http://invalid_odoh_config.com", true); +}); + +add_task(async function ensureODoHConfig() { + Services.prefs.setBoolPref("network.trr.odoh.enabled", true); + // Make sure we can connect to ODOH target successfully. + Services.prefs.setCharPref( + "network.dns.localDomains", + "odoh_host.example.com" + ); + + // Make sure we have an usable ODoHConfig to use. + await ODoHConfigTestHTTP( + `https://foo.example.com:${h2Port}/odohconfig?downloadFrom=http`, + true + ); +}); + +add_task(test_A_record); + +add_task(test_AAAA_records); + +add_task(test_RFC1918); + +add_task(test_GET_ECS); + +add_task(test_timeout_mode3); + +add_task(test_strict_native_fallback); + +add_task(test_no_answers_fallback); + +add_task(test_404_fallback); + +add_task(test_mode_1_and_4); + +add_task(test_CNAME); + +add_task(test_name_mismatch); + +add_task(test_mode_2); + +add_task(test_excluded_domains); + +add_task(test_captiveportal_canonicalURL); + +add_task(test_parentalcontrols); + +// TRR-first check that DNS result is used if domain is part of the builtin-excluded-domains pref +add_task(test_builtin_excluded_domains); + +add_task(test_excluded_domains_mode3); + +add_task(test25e); + +add_task(test_parentalcontrols_mode3); + +add_task(test_builtin_excluded_domains_mode3); + +add_task(count_cookies); + +add_task(test_connection_closed); + +add_task(test_fetch_time); + +add_task(test_fqdn); + +add_task(test_ipv6_trr_fallback); + +add_task(test_ipv4_trr_fallback); + +add_task(test_no_retry_without_doh); + +add_task(test_connection_reuse_and_cycling).skip(); // Bug 1742743 + +add_task(async function testODoHConfigNotAvailableInMode3() { + Services.dns.clearCache(true); + Services.prefs.setIntPref("network.trr.mode", 3); + Services.prefs.setCharPref("network.trr.uri", ""); + + await ODoHConfigTestHTTP("https://failed_odoh_config.com", false); + + // In mode 3, the DNS lookup should fail. + let { inStatus } = await new TRRDNSListener("test.example.com", { + expectedSuccess: false, + }); + + Assert.equal(inStatus, Cr.NS_ERROR_UNKNOWN_HOST); +}); + +add_task(async function testODoHConfigNotAvailableInMode2() { + Services.dns.clearCache(true); + Services.prefs.setIntPref("network.trr.mode", 2); + Services.prefs.setCharPref("network.trr.uri", ""); + + await ODoHConfigTestHTTP("https://failed_odoh_config_1.com", false); + + // In mode 2, we fallback to native. + await new TRRDNSListener("test.example.com", "127.0.0.1"); +}); |