Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/netwerk/test/unit/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 12 kB image not shown  

Quelle  test_trr_connection_cycle.js   Sprache: JAVA

 

"use strict";

/* import-globals-from trr_common.js */
/* import-globals-from head_trr.js */

const { TestUtils } = ChromeUtils.importESModule(
  "resource://testing-common/TestUtils.sys.mjs"
);

function setLocalModeAndURI(mode, url) {
  Services.prefs.setCharPref("network.trr.uri", url);
  Services.prefs.setIntPref("network.trr.mode", mode);
}

async function registerNS() {
  await trrServer.registerDoHAnswers("confirm.example.com", "NS", {
    answers: [
      {
        name: "confirm.example.com",
        ttl: 55,
        type: "NS",
        flush: false,
        data: "test.com",
      },
    ],
  });
}

async function unregisterNS() {
  await trrServer.registerDoHAnswers("confirm.example.com", "NS", {
    answers: [],
    error: 500, // Server error
  });
}

async function registerDomain(domain) {
  await trrServer.registerDoHAnswers(domain, "A", {
    answers: [
      {
        name: domain,
        ttl: 55,
        type: "A",
        flush: false,
        data: "9.8.7.6",
      },
    ],
  });
}

let trrServer;
add_setup(async function setup() {
  trr_test_setup();
  Services.prefs.setBoolPref("network.dns.native-is-localhost", true);
  Services.dns.clearCache(true);
  Services.prefs.setIntPref("network.trr.request_timeout_ms", 500);
  Services.prefs.setIntPref(
    "network.trr.strict_fallback_request_timeout_ms",
    500
  );
  Services.prefs.setIntPref("network.trr.request_timeout_mode_trronly_ms", 500);

  trrServer = new TRRServer();
  registerCleanupFunction(async () => {
    await trrServer.stop();
  });
  await trrServer.start();
  dump(`port = ${trrServer.port()}\n`);
  await registerNS();
});

// This test checks that connection is cycled on every failure when network.trr.retry_on_recoverable_errors is true.
add_task(async function test_connection_reuse_and_cycling() {
  Services.prefs.setCharPref(
    "network.trr.confirmationNS",
    "confirm.example.com"
  );
  setLocalModeAndURI(
    2,
    `https://foo.example.com:${trrServer.port()}/dns-query`
  );
  Services.prefs.setBoolPref("network.trr.strict_native_fallback", true);
  Services.prefs.setBoolPref("network.trr.retry_on_recoverable_errors", true);

  await TestUtils.waitForCondition(
    // 2 => CONFIRM_OK
    () => Services.dns.currentTrrConfirmationState == 2,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );

  // Setting conncycle=true in the URI. Server will start logging reqs.
  // We will do a specific sequence of lookups, then fetch the log from
  // the server and check that it matches what we'd expect.
  setLocalModeAndURI(
    2,
    `https://foo.example.com:${trrServer.port()}/dns-query?conncycle=true`
  );
  await TestUtils.waitForCondition(
    // 2 => CONFIRM_OK
    () => Services.dns.currentTrrConfirmationState == 2,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );
  // Confirmation upon uri-change will have created one req.

  for (let i = 1; i <= 6; i++) {
    await registerDomain(`bar${i}.example.org`);
  }
  await registerDomain("newconn.example.org");
  await registerDomain("newconn2.example.org");

  // Two reqs for each bar1 and bar2 - A + AAAA.
  await new TRRDNSListener("bar1.example.org", "9.8.7.6");
  await new TRRDNSListener("bar2.example.org", "9.8.7.6");
  // Total so far: (1) + 2 + 2 = 5

  // Two reqs that fail, one Confirmation req, two retried reqs that succeed.
  await new TRRDNSListener("newconn.example.org", "9.8.7.6");
  await TestUtils.waitForCondition(
    // 2 => CONFIRM_OK
    () => Services.dns.currentTrrConfirmationState == 2,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );
  // Total so far: (5) + 2 + 1 + 2 = 10

  // Two reqs for each bar3 and bar4 .
  await new TRRDNSListener("bar3.example.org", "9.8.7.6");
  await new TRRDNSListener("bar4.example.org", "9.8.7.6");
  // Total so far: (10) + 2 + 2 = 14.

  // Two reqs that fail, one Confirmation req, two retried reqs that succeed.
  await new TRRDNSListener("newconn2.example.org", "9.8.7.6");
  await TestUtils.waitForCondition(
    // 2 => CONFIRM_OK
    () => Services.dns.currentTrrConfirmationState == 2,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );
  // Total so far: (14) + 2 + 1 + 2 = 19

  // Two reqs for each bar5 and bar6 .
  await new TRRDNSListener("bar5.example.org", "9.8.7.6");
  await new TRRDNSListener("bar6.example.org", "9.8.7.6");
  // Total so far: (19) + 2 + 2 = 23

  let dohReqPortLog = await trrServer.execute(`global.gDoHPortsLog`);
  info(JSON.stringify(dohReqPortLog));

  // Since the actual ports seen will vary at runtime, we use placeholders
  // instead in our expected output definition. For example, if two entries
  // both have "port1", it means they both should have the same port in the
  // server's log.
  // For reqs that fail and trigger a Confirmation + retry, the retried reqs
  // might not re-use the new connection created for Confirmation due to a
  // race, so we have an extra alternate expected port for them. This lets
  // us test that they use *a* new port even if it's not *the* new port.
  // Subsequent lookups are not affected, they will use the same conn as
  // the Confirmation req.
  let expectedLogTemplate = [
    ["confirm.example.com", "port1"],
    ["bar1.example.org", "port1"],
    ["bar1.example.org", "port1"],
    ["bar2.example.org", "port1"],
    ["bar2.example.org", "port1"],
    ["newconn.example.org", "port1"],
    ["newconn.example.org", "port1"],
    ["confirm.example.com", "port2"],
    ["newconn.example.org", "port2"],
    ["newconn.example.org", "port2"],
    ["bar3.example.org", "port2"],
    ["bar3.example.org", "port2"],
    ["bar4.example.org", "port2"],
    ["bar4.example.org", "port2"],
    ["newconn2.example.org", "port2"],
    ["newconn2.example.org", "port2"],
    ["confirm.example.com", "port3"],
    ["newconn2.example.org", "port3"],
    ["newconn2.example.org", "port3"],
    ["bar5.example.org", "port3"],
    ["bar5.example.org", "port3"],
    ["bar6.example.org", "port3"],
    ["bar6.example.org", "port3"],
  ];

  if (expectedLogTemplate.length != dohReqPortLog.length) {
    // This shouldn't happen, and if it does, we'll fail the assertion
    // below. But first dump the whole server-side log to help with
    // debugging should we see a failure. Most likely cause would be
    // that another consumer of TRR happened to make a request while
    // the test was running and polluted the log.
    info(dohReqPortLog);
  }

  equal(
    expectedLogTemplate.length,
    dohReqPortLog.length,
    "Correct number of req log entries"
  );

  let seenPorts = new Set();
  // This is essentially a symbol table - as we iterate through the log
  // we will assign the actual seen port numbers to the placeholders.
  let seenPortsByExpectedPort = new Map();

  for (let i = 0; i < expectedLogTemplate.length; i++) {
    let expectedName = expectedLogTemplate[i][0];
    let expectedPort = expectedLogTemplate[i][1];
    let seenName = dohReqPortLog[i][0];
    let seenPort = dohReqPortLog[i][1];
    info(`Checking log entry. Name: ${seenName}, Port: ${seenPort}`);
    equal(expectedName, seenName, "Name matches for entry " + i);
    if (!seenPortsByExpectedPort.has(expectedPort)) {
      ok(!seenPorts.has(seenPort), "Port should not have been previously used");
      seenPorts.add(seenPort);
      seenPortsByExpectedPort.set(expectedPort, seenPort);
    } else {
      equal(
        seenPort,
        seenPortsByExpectedPort.get(expectedPort),
        "Connection was reused as expected"
      );
    }
  }

  // Clear log for the next test.
  await trrServer.execute(
    `global.gDoHPortsLog = []; global.gDoHNewConnLog = {};`
  );
});

// network.trr.retry_on_recoverable_errors = false
// This test unregisters the confirmation NS (server will return HTTP error code 500) before newconn resolutions
// The newconn resolutions will fail, triggering a confirmation. The second confirmation will cycle the connection.
// We check that the connection is cycled at least once for every newconn resolution.
add_task(async function test_connection_reuse_and_cycling2() {
  Services.prefs.setBoolPref("network.trr.retry_on_recoverable_errors", false);
  Services.dns.clearCache(true);
  Services.prefs.setCharPref(
    "network.trr.confirmationNS",
    "confirm.example.com"
  );
  setLocalModeAndURI(
    2,
    `https://foo.example.com:${trrServer.port()}/dns-query`
  );
  Services.prefs.setBoolPref("network.trr.strict_native_fallback", true);

  await TestUtils.waitForCondition(
    // 2 => CONFIRM_OK
    () => Services.dns.currentTrrConfirmationState == 2,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );

  // Setting conncycle=true in the URI. Server will start logging reqs.
  // We will do a specific sequence of lookups, then fetch the log from
  // the server and check that it matches what we'd expect.
  setLocalModeAndURI(
    2,
    `https://foo.example.com:${trrServer.port()}/dns-query?conncycle=true`
  );
  await TestUtils.waitForCondition(
    // 2 => CONFIRM_OK
    () => Services.dns.currentTrrConfirmationState == 2,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );
  // Confirmation upon uri-change will have created one req.

  for (let i = 1; i <= 6; i++) {
    await registerDomain(`bar${i}.example.org`);
  }
  await registerDomain("newconn.example.org");
  await registerDomain("newconn2.example.org");

  await new TRRDNSListener("bar1.example.org", "9.8.7.6");
  await new TRRDNSListener("bar2.example.org", "9.8.7.6");

  let initialPort = await trrServer.execute(
    `global.gDoHPortsLog[global.gDoHPortsLog.length-1]`
  );
  // This one will fallback because of the timeout
  await unregisterNS();
  await new TRRDNSListener("newconn.example.org", "127.0.0.1");
  await TestUtils.waitForCondition(
    // 3 => CONFIRM_FAILED
    () => Services.dns.currentTrrConfirmationState == 3,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );
  await registerNS();

  await TestUtils.waitForCondition(
    // 2 => CONFIRM_OK
    () => Services.dns.currentTrrConfirmationState == 2,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );
  let newConfirmationPort = await trrServer.execute(
    `global.gDoHPortsLog[global.gDoHPortsLog.length-1]`
  );

  // Two reqs for each bar3 and bar4 .
  await new TRRDNSListener("bar3.example.org", "9.8.7.6");
  await new TRRDNSListener("bar4.example.org", "9.8.7.6");

  initialPort = await trrServer.execute(
    `global.gDoHPortsLog[global.gDoHPortsLog.length-1]`
  );
  await unregisterNS();
  // This one will fallback because of the timeout
  await new TRRDNSListener("newconn2.example.org", "127.0.0.1");
  await TestUtils.waitForCondition(
    // 3 => CONFIRM_FAILED
    () => Services.dns.currentTrrConfirmationState == 3,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );
  await registerNS();

  await TestUtils.waitForCondition(
    // 2 => CONFIRM_OK
    () => Services.dns.currentTrrConfirmationState == 2,
    `Timed out waiting for confirmation success. Currently ${Services.dns.currentTrrConfirmationState}`,
    1,
    5000
  );
  newConfirmationPort = await trrServer.execute(
    `global.gDoHPortsLog[global.gDoHPortsLog.length-1]`
  );
  notEqual(
    initialPort,
    newConfirmationPort,
    "Failed confirmation must cycle the connection"
  );

  // Two reqs for each bar5 and bar6 .
  await new TRRDNSListener("bar5.example.org", "9.8.7.6");
  await new TRRDNSListener("bar6.example.org", "9.8.7.6");

  let dohReqPortLog = await trrServer.execute(`global.gDoHPortsLog`);

  const uniquePorts = new Set(dohReqPortLog.map(([_, port]) => port));
  if (uniquePorts.size < 3) {
    info(JSON.stringify(dohReqPortLog));
  }

  greaterOrEqual(
    uniquePorts.size,
    3,
    "Connection must be cycled at least twice"
  );
});

Messung V0.5 in Prozent
C=83 H=53 G=69

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-10-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.