Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / netwerk / test / unit / test_http3_fast_fallback.js
blob6498a96bf74be64dc4e60efde0e799838f9ddf37
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/. */
5 "use strict";
7 var { setTimeout } = ChromeUtils.importESModule(
8 "resource://gre/modules/Timer.sys.mjs"
9 );
11 let h2Port;
12 let h3Port;
13 let trrServer;
15 const { TestUtils } = ChromeUtils.importESModule(
16 "resource://testing-common/TestUtils.sys.mjs"
18 const certOverrideService = Cc[
19 "@mozilla.org/security/certoverride;1"
20 ].getService(Ci.nsICertOverrideService);
22 add_setup(async function setup() {
23 h2Port = Services.env.get("MOZHTTP2_PORT");
24 Assert.notEqual(h2Port, null);
25 Assert.notEqual(h2Port, "");
27 h3Port = Services.env.get("MOZHTTP3_PORT_NO_RESPONSE");
28 Assert.notEqual(h3Port, null);
29 Assert.notEqual(h3Port, "");
31 trr_test_setup();
33 if (mozinfo.socketprocess_networking) {
34 Services.dns; // Needed to trigger socket process.
35 await TestUtils.waitForCondition(() => Services.io.socketProcessLaunched);
38 Services.prefs.setIntPref("network.trr.mode", 2); // TRR first
39 Services.prefs.setBoolPref("network.http.http3.enable", true);
40 Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
41 Services.prefs.setBoolPref(
42 "network.dns.https_rr.check_record_with_cname",
43 false
46 registerCleanupFunction(async () => {
47 trr_clear_prefs();
48 Services.prefs.clearUserPref("network.dns.upgrade_with_https_rr");
49 Services.prefs.clearUserPref("network.dns.use_https_rr_as_altsvc");
50 Services.prefs.clearUserPref("network.dns.echconfig.enabled");
51 Services.prefs.clearUserPref("network.dns.http3_echconfig.enabled");
52 Services.prefs.clearUserPref(
53 "network.dns.echconfig.fallback_to_origin_when_all_failed"
55 Services.prefs.clearUserPref("network.dns.httpssvc.reset_exclustion_list");
56 Services.prefs.clearUserPref("network.http.http3.enable");
57 Services.prefs.clearUserPref(
58 "network.dns.httpssvc.http3_fast_fallback_timeout"
60 Services.prefs.clearUserPref(
61 "network.http.http3.alt-svc-mapping-for-testing"
63 Services.prefs.clearUserPref("network.http.http3.backup_timer_delay");
64 Services.prefs.clearUserPref("network.http.speculative-parallel-limit");
65 Services.prefs.clearUserPref(
66 "network.http.http3.parallel_fallback_conn_limit"
68 Services.prefs.clearUserPref(
69 "network.dns.https_rr.check_record_with_cname"
71 if (trrServer) {
72 await trrServer.stop();
74 });
75 });
77 function makeChan(url) {
78 let chan = NetUtil.newChannel({
79 uri: url,
80 loadUsingSystemPrincipal: true,
81 contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
82 }).QueryInterface(Ci.nsIHttpChannel);
83 chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
84 return chan;
87 function channelOpenPromise(chan, flags, delay) {
88 // eslint-disable-next-line no-async-promise-executor
89 return new Promise(async resolve => {
90 function finish(req, buffer) {
91 resolve([req, buffer]);
92 certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
93 false
96 certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
97 true
99 if (delay) {
100 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
101 await new Promise(r => setTimeout(r, delay));
103 chan.asyncOpen(new ChannelListener(finish, null, flags));
107 let CheckOnlyHttp2Listener = function () {};
109 CheckOnlyHttp2Listener.prototype = {
110 onStartRequest: function testOnStartRequest() {},
112 onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
113 read_stream(stream, cnt);
116 onStopRequest: function testOnStopRequest(request, status) {
117 Assert.equal(status, Cr.NS_OK);
118 let httpVersion = "";
119 try {
120 httpVersion = request.protocolVersion;
121 } catch (e) {}
122 Assert.equal(httpVersion, "h2");
124 let routed = "NA";
125 try {
126 routed = request.getRequestHeader("Alt-Used");
127 } catch (e) {}
128 dump("routed is " + routed + "\n");
129 Assert.ok(routed === "0" || routed === "NA");
130 this.finish();
134 async function fast_fallback_test() {
135 let result = 1;
136 // We need to loop here because we need to wait for AltSvc storage to
137 // to be started.
138 // We also do not have a way to verify that HTTP3 has been tried, because
139 // the fallback is automatic, so try a couple of times.
140 do {
141 // We need to close HTTP2 connections, otherwise our connection pooling
142 // will dispatch the request over already existing HTTP2 connection.
143 Services.obs.notifyObservers(null, "net:prune-all-connections");
144 let chan = makeChan(`https://foo.example.com:${h2Port}/`);
145 let listener = new CheckOnlyHttp2Listener();
146 await altsvcSetupPromise(chan, listener);
147 result++;
148 } while (result < 3);
151 // Test the case when speculative connection is enabled. In this case, when the
152 // backup connection is ready, the http transaction is still in pending
153 // queue because the h3 connection is never ready to accept transactions.
154 add_task(async function test_fast_fallback_with_speculative_connection() {
155 Services.prefs.setBoolPref("network.http.http3.enable", true);
156 Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com");
157 // Set AltSvc to point to not existing HTTP3 server on port 443
158 Services.prefs.setCharPref(
159 "network.http.http3.alt-svc-mapping-for-testing",
160 "foo.example.com;h3=:" + h3Port
162 Services.prefs.setBoolPref("network.dns.disableIPv6", true);
163 Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
165 await fast_fallback_test();
168 // Test the case when speculative connection is disabled. In this case, when the
169 // back connection is ready, the http transaction is already activated,
170 // but the socket is not ready to write.
171 add_task(async function test_fast_fallback_without_speculative_connection() {
172 // Make sure the h3 connection created by the previous test is cleared.
173 Services.obs.notifyObservers(null, "net:cancel-all-connections");
174 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
175 await new Promise(resolve => setTimeout(resolve, 1000));
176 // Clear the h3 excluded list, otherwise the Alt-Svc mapping will not be used.
177 Services.obs.notifyObservers(null, "network:reset-http3-excluded-list");
178 Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
180 await fast_fallback_test();
182 Services.prefs.clearUserPref(
183 "network.http.http3.alt-svc-mapping-for-testing"
187 // Test when echConfig is disabled and we have https rr for http3. We use a
188 // longer timeout in this test, so when fast fallback timer is triggered, the
189 // http transaction is already activated.
190 add_task(async function testFastfallback() {
191 trrServer = new TRRServer();
192 await trrServer.start();
193 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
194 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
195 Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
197 Services.prefs.setIntPref("network.trr.mode", 3);
198 Services.prefs.setCharPref(
199 "network.trr.uri",
200 `https://foo.example.com:${trrServer.port()}/dns-query`
202 Services.prefs.setBoolPref("network.http.http3.enable", true);
204 Services.prefs.setIntPref(
205 "network.dns.httpssvc.http3_fast_fallback_timeout",
206 1000
209 await trrServer.registerDoHAnswers("test.fastfallback.com", "HTTPS", {
210 answers: [
212 name: "test.fastfallback.com",
213 ttl: 55,
214 type: "HTTPS",
215 flush: false,
216 data: {
217 priority: 1,
218 name: "test.fastfallback1.com",
219 values: [
220 { key: "alpn", value: "h3" },
221 { key: "no-default-alpn" },
222 { key: "port", value: h3Port },
223 { key: "echconfig", value: "456..." },
228 name: "test.fastfallback.com",
229 ttl: 55,
230 type: "HTTPS",
231 flush: false,
232 data: {
233 priority: 2,
234 name: "test.fastfallback2.com",
235 values: [
236 { key: "alpn", value: "h2" },
237 { key: "port", value: h2Port },
238 { key: "echconfig", value: "456..." },
245 await trrServer.registerDoHAnswers("test.fastfallback1.com", "A", {
246 answers: [
248 name: "test.fastfallback1.com",
249 ttl: 55,
250 type: "A",
251 flush: false,
252 data: "127.0.0.1",
257 await trrServer.registerDoHAnswers("test.fastfallback2.com", "A", {
258 answers: [
260 name: "test.fastfallback2.com",
261 ttl: 55,
262 type: "A",
263 flush: false,
264 data: "127.0.0.1",
269 let chan = makeChan(`https://test.fastfallback.com/server-timing`);
270 let [req] = await channelOpenPromise(chan);
271 Assert.equal(req.protocolVersion, "h2");
272 let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
273 Assert.equal(internal.remotePort, h2Port);
275 await trrServer.stop();
278 // Like the previous test, but with a shorter timeout, so when fast fallback
279 // timer is triggered, the http transaction is still in pending queue.
280 add_task(async function testFastfallback1() {
281 trrServer = new TRRServer();
282 await trrServer.start();
283 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
284 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
285 Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
287 Services.prefs.setIntPref("network.trr.mode", 3);
288 Services.prefs.setCharPref(
289 "network.trr.uri",
290 `https://foo.example.com:${trrServer.port()}/dns-query`
292 Services.prefs.setBoolPref("network.http.http3.enable", true);
294 Services.prefs.setIntPref(
295 "network.dns.httpssvc.http3_fast_fallback_timeout",
299 await trrServer.registerDoHAnswers("test.fastfallback.org", "HTTPS", {
300 answers: [
302 name: "test.fastfallback.org",
303 ttl: 55,
304 type: "HTTPS",
305 flush: false,
306 data: {
307 priority: 1,
308 name: "test.fastfallback1.org",
309 values: [
310 { key: "alpn", value: "h3" },
311 { key: "no-default-alpn" },
312 { key: "port", value: h3Port },
313 { key: "echconfig", value: "456..." },
318 name: "test.fastfallback.org",
319 ttl: 55,
320 type: "HTTPS",
321 flush: false,
322 data: {
323 priority: 2,
324 name: "test.fastfallback2.org",
325 values: [
326 { key: "alpn", value: "h2" },
327 { key: "port", value: h2Port },
328 { key: "echconfig", value: "456..." },
335 await trrServer.registerDoHAnswers("test.fastfallback1.org", "A", {
336 answers: [
338 name: "test.fastfallback1.org",
339 ttl: 55,
340 type: "A",
341 flush: false,
342 data: "127.0.0.1",
347 await trrServer.registerDoHAnswers("test.fastfallback2.org", "A", {
348 answers: [
350 name: "test.fastfallback2.org",
351 ttl: 55,
352 type: "A",
353 flush: false,
354 data: "127.0.0.1",
359 let chan = makeChan(`https://test.fastfallback.org/server-timing`);
360 let [req] = await channelOpenPromise(chan);
361 Assert.equal(req.protocolVersion, "h2");
362 let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
363 Assert.equal(internal.remotePort, h2Port);
365 await trrServer.stop();
368 // Test when echConfig is enabled, we can sucessfully fallback to the last
369 // record.
370 add_task(async function testFastfallbackWithEchConfig() {
371 trrServer = new TRRServer();
372 await trrServer.start();
373 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
374 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
375 Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
376 Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
378 Services.prefs.setIntPref("network.trr.mode", 3);
379 Services.prefs.setCharPref(
380 "network.trr.uri",
381 `https://foo.example.com:${trrServer.port()}/dns-query`
383 Services.prefs.setBoolPref("network.http.http3.enable", true);
385 Services.prefs.setIntPref(
386 "network.dns.httpssvc.http3_fast_fallback_timeout",
390 await trrServer.registerDoHAnswers("test.ech.org", "HTTPS", {
391 answers: [
393 name: "test.ech.org",
394 ttl: 55,
395 type: "HTTPS",
396 flush: false,
397 data: {
398 priority: 1,
399 name: "test.ech1.org",
400 values: [
401 { key: "alpn", value: "h3" },
402 { key: "port", value: h3Port },
403 { key: "echconfig", value: "456..." },
408 name: "test.ech.org",
409 ttl: 55,
410 type: "HTTPS",
411 flush: false,
412 data: {
413 priority: 2,
414 name: "test.ech2.org",
415 values: [
416 { key: "alpn", value: "h2" },
417 { key: "port", value: h2Port },
418 { key: "echconfig", value: "456..." },
423 name: "test.ech.org",
424 ttl: 55,
425 type: "HTTPS",
426 flush: false,
427 data: {
428 priority: 3,
429 name: "test.ech3.org",
430 values: [
431 { key: "alpn", value: "h2" },
432 { key: "port", value: h2Port },
433 { key: "echconfig", value: "456..." },
440 await trrServer.registerDoHAnswers("test.ech1.org", "A", {
441 answers: [
443 name: "test.ech1.org",
444 ttl: 55,
445 type: "A",
446 flush: false,
447 data: "127.0.0.1",
452 await trrServer.registerDoHAnswers("test.ech3.org", "A", {
453 answers: [
455 name: "test.ech3.org",
456 ttl: 55,
457 type: "A",
458 flush: false,
459 data: "127.0.0.1",
464 let chan = makeChan(`https://test.ech.org/server-timing`);
465 let [req] = await channelOpenPromise(chan);
466 Assert.equal(req.protocolVersion, "h2");
467 let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
468 Assert.equal(internal.remotePort, h2Port);
470 await trrServer.stop();
473 // Test when echConfig is enabled, the connection should fail when not all
474 // records have echConfig.
475 add_task(async function testFastfallbackWithpartialEchConfig() {
476 trrServer = new TRRServer();
477 await trrServer.start();
478 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
479 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
480 Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
481 Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
483 Services.prefs.setIntPref("network.trr.mode", 3);
484 Services.prefs.setCharPref(
485 "network.trr.uri",
486 `https://foo.example.com:${trrServer.port()}/dns-query`
488 Services.prefs.setBoolPref("network.http.http3.enable", true);
490 Services.prefs.setIntPref(
491 "network.dns.httpssvc.http3_fast_fallback_timeout",
495 await trrServer.registerDoHAnswers("test.partial_ech.org", "HTTPS", {
496 answers: [
498 name: "test.partial_ech.org",
499 ttl: 55,
500 type: "HTTPS",
501 flush: false,
502 data: {
503 priority: 1,
504 name: "test.partial_ech1.org",
505 values: [
506 { key: "alpn", value: "h3" },
507 { key: "port", value: h3Port },
508 { key: "echconfig", value: "456..." },
513 name: "test.partial_ech.org",
514 ttl: 55,
515 type: "HTTPS",
516 flush: false,
517 data: {
518 priority: 2,
519 name: "test.partial_ech2.org",
520 values: [
521 { key: "alpn", value: "h2" },
522 { key: "port", value: h2Port },
529 await trrServer.registerDoHAnswers("test.partial_ech1.org", "A", {
530 answers: [
532 name: "test.partial_ech1.org",
533 ttl: 55,
534 type: "A",
535 flush: false,
536 data: "127.0.0.1",
541 await trrServer.registerDoHAnswers("test.partial_ech2.org", "A", {
542 answers: [
544 name: "test.partial_ech2.org",
545 ttl: 55,
546 type: "A",
547 flush: false,
548 data: "127.0.0.1",
553 let chan = makeChan(`https://test.partial_ech.org/server-timing`);
554 await channelOpenPromise(chan, CL_EXPECT_LATE_FAILURE | CL_ALLOW_UNKNOWN_CL);
556 await trrServer.stop();
559 add_task(async function testFastfallbackWithoutEchConfig() {
560 trrServer = new TRRServer();
561 await trrServer.start();
562 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
563 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
565 Services.prefs.setIntPref("network.trr.mode", 3);
566 Services.prefs.setCharPref(
567 "network.trr.uri",
568 `https://foo.example.com:${trrServer.port()}/dns-query`
570 Services.prefs.setBoolPref("network.http.http3.enable", true);
572 Services.prefs.setIntPref(
573 "network.dns.httpssvc.http3_fast_fallback_timeout",
577 await trrServer.registerDoHAnswers("test.no_ech_h2.org", "HTTPS", {
578 answers: [
580 name: "test.no_ech_h2.org",
581 ttl: 55,
582 type: "HTTPS",
583 flush: false,
584 data: {
585 priority: 1,
586 name: "test.no_ech_h3.org",
587 values: [
588 { key: "alpn", value: "h3" },
589 { key: "port", value: h3Port },
596 await trrServer.registerDoHAnswers("test.no_ech_h3.org", "A", {
597 answers: [
599 name: "test.no_ech_h3.org",
600 ttl: 55,
601 type: "A",
602 flush: false,
603 data: "127.0.0.1",
608 await trrServer.registerDoHAnswers("test.no_ech_h2.org", "A", {
609 answers: [
611 name: "test.no_ech_h2.org",
612 ttl: 55,
613 type: "A",
614 flush: false,
615 data: "127.0.0.1",
620 let chan = makeChan(`https://test.no_ech_h2.org:${h2Port}/server-timing`);
621 let [req] = await channelOpenPromise(chan);
622 Assert.equal(req.protocolVersion, "h2");
623 let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
624 Assert.equal(internal.remotePort, h2Port);
626 await trrServer.stop();
629 add_task(async function testH3FallbackWithMultipleTransactions() {
630 trrServer = new TRRServer();
631 await trrServer.start();
632 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
633 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
634 Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
636 Services.prefs.setIntPref("network.trr.mode", 3);
637 Services.prefs.setCharPref(
638 "network.trr.uri",
639 `https://foo.example.com:${trrServer.port()}/dns-query`
641 Services.prefs.setBoolPref("network.http.http3.enable", true);
643 // Disable fast fallback.
644 Services.prefs.setIntPref(
645 "network.http.http3.parallel_fallback_conn_limit",
648 Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
650 await trrServer.registerDoHAnswers("test.multiple_trans.org", "HTTPS", {
651 answers: [
653 name: "test.multiple_trans.org",
654 ttl: 55,
655 type: "HTTPS",
656 flush: false,
657 data: {
658 priority: 1,
659 name: "test.multiple_trans.org",
660 values: [
661 { key: "alpn", value: "h3" },
662 { key: "port", value: h3Port },
669 await trrServer.registerDoHAnswers("test.multiple_trans.org", "A", {
670 answers: [
672 name: "test.multiple_trans.org",
673 ttl: 55,
674 type: "A",
675 flush: false,
676 data: "127.0.0.1",
681 let promises = [];
682 for (let i = 0; i < 2; ++i) {
683 let chan = makeChan(
684 `https://test.multiple_trans.org:${h2Port}/server-timing`
686 promises.push(channelOpenPromise(chan));
689 let res = await Promise.all(promises);
690 res.forEach(function (e) {
691 let [req] = e;
692 Assert.equal(req.protocolVersion, "h2");
693 let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
694 Assert.equal(internal.remotePort, h2Port);
697 await trrServer.stop();
700 add_task(async function testTwoFastFallbackTimers() {
701 trrServer = new TRRServer();
702 await trrServer.start();
703 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
704 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
705 Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
707 Services.prefs.setIntPref("network.trr.mode", 3);
708 Services.prefs.setCharPref(
709 "network.trr.uri",
710 `https://foo.example.com:${trrServer.port()}/dns-query`
712 Services.prefs.setBoolPref("network.http.http3.enable", true);
714 Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
715 Services.prefs.clearUserPref(
716 "network.http.http3.parallel_fallback_conn_limit"
719 Services.prefs.setCharPref(
720 "network.http.http3.alt-svc-mapping-for-testing",
721 "foo.fallback.org;h3=:" + h3Port
724 Services.prefs.setIntPref(
725 "network.dns.httpssvc.http3_fast_fallback_timeout",
728 Services.prefs.setIntPref("network.http.http3.backup_timer_delay", 100);
730 await trrServer.registerDoHAnswers("foo.fallback.org", "HTTPS", {
731 answers: [
733 name: "foo.fallback.org",
734 ttl: 55,
735 type: "HTTPS",
736 flush: false,
737 data: {
738 priority: 1,
739 name: "foo.fallback.org",
740 values: [
741 { key: "alpn", value: "h3" },
742 { key: "port", value: h3Port },
749 await trrServer.registerDoHAnswers("foo.fallback.org", "A", {
750 answers: [
752 name: "foo.fallback.org",
753 ttl: 55,
754 type: "A",
755 flush: false,
756 data: "127.0.0.1",
761 // Test the case that http3 backup timer is triggered after
762 // fast fallback timer or HTTPS RR.
763 Services.prefs.setIntPref(
764 "network.dns.httpssvc.http3_fast_fallback_timeout",
767 Services.prefs.setIntPref("network.http.http3.backup_timer_delay", 100);
769 async function createChannelAndStartTest() {
770 let chan = makeChan(`https://foo.fallback.org:${h2Port}/server-timing`);
771 let [req] = await channelOpenPromise(chan);
772 Assert.equal(req.protocolVersion, "h2");
773 let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
774 Assert.equal(internal.remotePort, h2Port);
777 await createChannelAndStartTest();
779 Services.obs.notifyObservers(null, "net:prune-all-connections");
780 Services.obs.notifyObservers(null, "network:reset-http3-excluded-list");
781 Services.dns.clearCache(true);
783 // Do the same test again, but with a different configuration.
784 Services.prefs.setIntPref(
785 "network.dns.httpssvc.http3_fast_fallback_timeout",
788 Services.prefs.setIntPref("network.http.http3.backup_timer_delay", 10);
790 await createChannelAndStartTest();
792 await trrServer.stop();
795 add_task(async function testH3FastFallbackWithMultipleTransactions() {
796 trrServer = new TRRServer();
797 await trrServer.start();
798 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
799 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
800 Services.prefs.setBoolPref("network.dns.echconfig.enabled", false);
802 Services.prefs.setIntPref("network.trr.mode", 3);
803 Services.prefs.setCharPref(
804 "network.trr.uri",
805 `https://foo.example.com:${trrServer.port()}/dns-query`
807 Services.prefs.setBoolPref("network.http.http3.enable", true);
809 Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
810 Services.prefs.clearUserPref(
811 "network.http.http3.parallel_fallback_conn_limit"
814 Services.prefs.setIntPref("network.http.http3.backup_timer_delay", 500);
816 Services.prefs.setCharPref(
817 "network.http.http3.alt-svc-mapping-for-testing",
818 "test.multiple_fallback_trans.org;h3=:" + h3Port
821 await trrServer.registerDoHAnswers("test.multiple_fallback_trans.org", "A", {
822 answers: [
824 name: "test.multiple_fallback_trans.org",
825 ttl: 55,
826 type: "A",
827 flush: false,
828 data: "127.0.0.1",
833 let promises = [];
834 for (let i = 0; i < 3; ++i) {
835 let chan = makeChan(
836 `https://test.multiple_fallback_trans.org:${h2Port}/server-timing`
838 if (i == 0) {
839 promises.push(channelOpenPromise(chan));
840 } else {
841 promises.push(channelOpenPromise(chan, null, 500));
845 let res = await Promise.all(promises);
846 res.forEach(function (e) {
847 let [req] = e;
848 Assert.equal(req.protocolVersion, "h2");
849 let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
850 Assert.equal(internal.remotePort, h2Port);
853 await trrServer.stop();
856 add_task(async function testFastfallbackToTheSameRecord() {
857 trrServer = new TRRServer();
858 await trrServer.start();
859 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
860 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
861 Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
862 Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", true);
864 Services.prefs.setIntPref("network.trr.mode", 3);
865 Services.prefs.setCharPref(
866 "network.trr.uri",
867 `https://foo.example.com:${trrServer.port()}/dns-query`
869 Services.prefs.setBoolPref("network.http.http3.enable", true);
871 Services.prefs.setIntPref(
872 "network.dns.httpssvc.http3_fast_fallback_timeout",
873 1000
876 await trrServer.registerDoHAnswers("test.ech.org", "HTTPS", {
877 answers: [
879 name: "test.ech.org",
880 ttl: 55,
881 type: "HTTPS",
882 flush: false,
883 data: {
884 priority: 1,
885 name: "test.ech1.org",
886 values: [
887 { key: "alpn", value: ["h3", "h2"] },
888 { key: "port", value: h2Port },
889 { key: "echconfig", value: "456..." },
896 await trrServer.registerDoHAnswers("test.ech1.org", "A", {
897 answers: [
899 name: "test.ech1.org",
900 ttl: 55,
901 type: "A",
902 flush: false,
903 data: "127.0.0.1",
908 let chan = makeChan(`https://test.ech.org/server-timing`);
909 let [req] = await channelOpenPromise(chan);
910 Assert.equal(req.protocolVersion, "h2");
911 let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
912 Assert.equal(internal.remotePort, h2Port);
914 await trrServer.stop();