1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 const { TestUtils
} = ChromeUtils
.importESModule(
8 "resource://testing-common/TestUtils.sys.mjs"
11 async
function waitForConfirmationState(state
, msToWait
= 0) {
12 await TestUtils
.waitForCondition(
13 () => Services
.dns
.currentTrrConfirmationState
== state
,
14 `Timed out waiting for ${state}. Currently ${Services.dns.currentTrrConfirmationState}`,
19 Services
.dns
.currentTrrConfirmationState
,
21 "expected confirmation state"
25 const CONFIRM_OFF
= 0;
26 const CONFIRM_TRYING_OK
= 1;
28 const CONFIRM_FAILED
= 3;
29 const CONFIRM_TRYING_FAILED
= 4;
30 const CONFIRM_DISABLED
= 5;
34 Services
.prefs
.setBoolPref("network.trr.skip-check-for-blocked-host", true);
38 registerCleanupFunction(async () => {
40 Services
.prefs
.clearUserPref("network.trr.skip-check-for-blocked-host");
44 add_task(async
function start_trr_server() {
45 trrServer
= new TRRServer();
46 registerCleanupFunction(async () => {
47 await trrServer
.stop();
49 await trrServer
.start();
50 dump(`port = ${trrServer.port()}\n`);
52 await trrServer
.registerDoHAnswers(`faily.com`, "NS", {
64 for (let i
= 0; i
< 15; i
++) {
65 await trrServer
.registerDoHAnswers(`failing-domain${i}.faily.com`, "A", {
68 await trrServer
.registerDoHAnswers(`failing-domain${i}.faily.com`, "AAAA", {
74 function trigger15Failures() {
75 // We need to clear the cache in case a previous call to this method
76 // put the results in the DNS cache.
77 Services
.dns
.clearCache(true);
80 // There are actually two TRR requests sent for A and AAAA records, so doing
81 // DNS query 10 times should be enough to trigger confirmation process.
82 for (let i
= 0; i
< 10; i
++) {
84 new TRRDNSListener(`failing-domain${i}.faily.com`, {
85 expectedAnswer
: "127.0.0.1",
90 return Promise
.all(dnsRequests
);
93 async
function registerNS(delay
) {
94 return trrServer
.registerDoHAnswers("confirm.example.com", "NS", {
97 name
: "confirm.example.com",
108 add_task(async
function confirm_off() {
109 Services
.prefs
.setCharPref(
110 "network.trr.confirmationNS",
111 "confirm.example.com"
113 Services
.prefs
.setIntPref(
115 Ci
.nsIDNSService
.MODE_NATIVEONLY
117 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OFF
);
118 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRROFF
);
119 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OFF
);
122 add_task(async
function confirm_disabled() {
123 Services
.prefs
.setCharPref(
124 "network.trr.confirmationNS",
125 "confirm.example.com"
127 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRRONLY
);
128 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_DISABLED
);
129 Services
.prefs
.setCharPref("network.trr.confirmationNS", "skip");
130 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRRFIRST
);
131 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_DISABLED
);
134 add_task(async
function confirm_ok() {
135 Services
.dns
.clearCache(true);
136 Services
.prefs
.setCharPref(
137 "network.trr.confirmationNS",
138 "confirm.example.com"
141 await trrServer
.registerDoHAnswers("example.com", "A", {
152 Services
.prefs
.setCharPref(
154 `https://foo.example.com:${trrServer.port()}/dns-query`
156 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRRFIRST
);
158 Services
.dns
.currentTrrConfirmationState
,
160 "Should be CONFIRM_TRYING_OK"
162 await
new TRRDNSListener("example.com", { expectedAnswer
: "1.2.3.4" });
163 equal(await trrServer
.requestCount("example.com", "A"), 1);
164 await
waitForConfirmationState(CONFIRM_OK
, 1000);
166 await
registerNS(500);
167 Services
.prefs
.setIntPref(
169 Ci
.nsIDNSService
.MODE_NATIVEONLY
171 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRRFIRST
);
173 Services
.dns
.currentTrrConfirmationState
,
175 "Should be CONFIRM_TRYING_OK"
177 await
new Promise(resolve
=> do_timeout(100, resolve
));
179 Services
.dns
.currentTrrConfirmationState
,
181 "Confirmation should still be pending"
183 await
waitForConfirmationState(CONFIRM_OK
, 1000);
186 add_task(async
function confirm_timeout() {
187 Services
.prefs
.setIntPref(
189 Ci
.nsIDNSService
.MODE_NATIVEONLY
191 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OFF
);
192 await
registerNS(7000);
193 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRRFIRST
);
195 Services
.dns
.currentTrrConfirmationState
,
197 "Should be CONFIRM_TRYING_OK"
199 await
waitForConfirmationState(CONFIRM_FAILED
, 7500);
200 // After the confirmation fails, a timer will periodically trigger a retry
201 // causing the state to go into CONFIRM_TRYING_FAILED.
202 await
waitForConfirmationState(CONFIRM_TRYING_FAILED
, 500);
205 add_task(async
function confirm_fail_fast() {
206 Services
.prefs
.setIntPref(
208 Ci
.nsIDNSService
.MODE_NATIVEONLY
210 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OFF
);
211 await trrServer
.registerDoHAnswers("confirm.example.com", "NS", {
214 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRRFIRST
);
216 Services
.dns
.currentTrrConfirmationState
,
218 "Should be CONFIRM_TRYING_OK"
220 await
waitForConfirmationState(CONFIRM_FAILED
, 100);
223 add_task(async
function multiple_failures() {
224 Services
.prefs
.setIntPref(
226 Ci
.nsIDNSService
.MODE_NATIVEONLY
228 Services
.prefs
.setIntPref("network.trr.max-retry-timeout-ms", 8000);
229 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OFF
);
231 await
registerNS(100);
232 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRRFIRST
);
234 Services
.dns
.currentTrrConfirmationState
,
236 "Should be CONFIRM_TRYING_OK"
238 await
waitForConfirmationState(CONFIRM_OK
, 1000);
239 await
registerNS(4000);
240 let failures
= trigger15Failures();
241 await
waitForConfirmationState(CONFIRM_TRYING_OK
, 3000);
243 // Check that failures during confirmation are ignored.
244 await
trigger15Failures();
246 Services
.dns
.currentTrrConfirmationState
,
248 "Should be CONFIRM_TRYING_OK"
250 await
waitForConfirmationState(CONFIRM_OK
, 8500);
253 add_task(async
function test_connectivity_change() {
254 await
registerNS(100);
255 Services
.prefs
.setIntPref(
257 Ci
.nsIDNSService
.MODE_NATIVEONLY
259 let confirmationCount
= await trrServer
.requestCount(
260 "confirm.example.com",
263 Services
.prefs
.setIntPref("network.trr.mode", Ci
.nsIDNSService
.MODE_TRRFIRST
);
265 Services
.dns
.currentTrrConfirmationState
,
267 "Should be CONFIRM_TRYING_OK"
269 await
waitForConfirmationState(CONFIRM_OK
, 1000);
271 await trrServer
.requestCount("confirm.example.com", "NS"),
272 confirmationCount
+ 1
274 Services
.obs
.notifyObservers(
276 "network:captive-portal-connectivity",
279 // This means a CP check completed successfully. But no CP was previously
280 // detected, so this is mostly a no-op.
281 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OK
);
283 Services
.obs
.notifyObservers(
285 "network:captive-portal-connectivity",
288 // This basically a successful CP login event. Wasn't captive before.
289 // Still treating as a no-op.
290 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OK
);
292 // This makes the TRR service set mCaptiveIsPassed=false
293 Services
.obs
.notifyObservers(
295 "captive-portal-login",
296 "{type: 'captive-portal-login', id: 0, url: 'http://localhost/'}"
299 await
registerNS(500);
300 let failures
= trigger15Failures();
301 // The failure should cause us to go into CONFIRM_TRYING_OK and do an NS req
302 await
waitForConfirmationState(CONFIRM_TRYING_OK
, 3000);
305 // The notification sets mCaptiveIsPassed=true then triggers an entirely new
307 Services
.obs
.notifyObservers(
309 "network:captive-portal-connectivity",
312 // The notification should cause us to send a new confirmation request
314 Services
.dns
.currentTrrConfirmationState
,
316 "Should be CONFIRM_TRYING_OK"
318 await
waitForConfirmationState(CONFIRM_OK
, 1000);
319 // two extra confirmation events should have been received by the server
321 await trrServer
.requestCount("confirm.example.com", "NS"),
322 confirmationCount
+ 3
326 add_task(async
function test_network_change() {
327 let confirmationCount
= await trrServer
.requestCount(
328 "confirm.example.com",
331 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OK
);
333 Services
.obs
.notifyObservers(null, "network:link-status-changed", "up");
334 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OK
);
336 await trrServer
.requestCount("confirm.example.com", "NS"),
340 let failures
= trigger15Failures();
341 // The failure should cause us to go into CONFIRM_TRYING_OK and do an NS req
342 await
waitForConfirmationState(CONFIRM_TRYING_OK
, 3000);
344 // The network up event should reset the confirmation to TRYING_OK and do
346 Services
.obs
.notifyObservers(null, "network:link-status-changed", "up");
347 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_TRYING_OK
);
348 await
waitForConfirmationState(CONFIRM_OK
, 1000);
349 // two extra confirmation events should have been received by the server
351 await trrServer
.requestCount("confirm.example.com", "NS"),
352 confirmationCount
+ 2
356 add_task(async
function test_uri_pref_change() {
357 let confirmationCount
= await trrServer
.requestCount(
358 "confirm.example.com",
361 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_OK
);
362 Services
.prefs
.setCharPref(
364 `https://foo.example.com:${trrServer.port()}/dns-query?changed`
366 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_TRYING_OK
);
367 await
waitForConfirmationState(CONFIRM_OK
, 1000);
369 await trrServer
.requestCount("confirm.example.com", "NS"),
370 confirmationCount
+ 1
374 add_task(async
function test_autodetected_uri() {
375 const defaultPrefBranch
= Services
.prefs
.getDefaultBranch("");
376 let defaultURI
= defaultPrefBranch
.getCharPref(
377 "network.trr.default_provider_uri"
379 defaultPrefBranch
.setCharPref(
380 "network.trr.default_provider_uri",
381 `https://foo.example.com:${trrServer.port()}/dns-query?changed`
383 // For setDetectedTrrURI to work we must pretend we are using the default.
384 Services
.prefs
.clearUserPref("network.trr.uri");
385 await
waitForConfirmationState(CONFIRM_OK
, 1000);
386 let confirmationCount
= await trrServer
.requestCount(
387 "confirm.example.com",
390 Services
.dns
.setDetectedTrrURI(
391 `https://foo.example.com:${trrServer.port()}/dns-query?changed2`
393 equal(Services
.dns
.currentTrrConfirmationState
, CONFIRM_TRYING_OK
);
394 await
waitForConfirmationState(CONFIRM_OK
, 1000);
396 await trrServer
.requestCount("confirm.example.com", "NS"),
397 confirmationCount
+ 1
400 // reset the default URI
401 defaultPrefBranch
.setCharPref("network.trr.default_provider_uri", defaultURI
);