Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  test_happy_eyeballs_0rtt_h1_reject.js   Sprache: JAVA

 

/* 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/. */


// Regression test for the alpnChanged=false path in ZeroRttHandle::Finish0RTT.
//
// When H1 0-RTT early data is rejected by the server (NSS reports
// earlyDataAccepted=false) but the ALPN is unchanged (H1→H1), the H1
// connection is still fully usable.  ZeroRttHandle::Finish0RTT must NOT
// close the HET; it must fall through to InvokeCallback(NS_OK) so HE
// declares the winner and the real transaction is adopted onto the live
// connection.
//
// Observable: the second request has resumed=true — the TLS session was
// resumed via PSK even though early data was rejected.  If the fix were
// absent (alpnChanged check missing), the PSK token would be evicted and
// the retry would open a fresh connection with resumed=false.
//
// ZeroRttAcceptServer's "0rtt-reject-h1.example.com" host omits the NSS
// anti-replay context so early data is always rejected without closing the
// connection.

"use strict";

const { AppConstants } = ChromeUtils.importESModule(
  "resource://gre/modules/AppConstants.sys.mjs"
);
const { HttpServer } = ChromeUtils.importESModule(
  "resource://testing-common/httpd.sys.mjs"
);
var { setTimeout } = ChromeUtils.importESModule(
  "resource://gre/modules/Timer.sys.mjs"
);

const override = Cc["@mozilla.org/network/native-dns-override;1"].getService(
  Ci.nsINativeDNSResolverOverride
);

const kHost = "0rtt-reject-h1.example.com";
const kPort = 8443;

let callbackServer;
let gServerStarted = false;

add_setup(
  {
    skip_if: () => AppConstants.MOZ_SYSTEM_NSS,
  },
  async () => {
    callbackServer = new HttpServer();
    callbackServer.registerPrefixHandler("/callback/", () => {});
    callbackServer.start(-1);

    Services.env.set(
      "MOZ_ZERORTT_ACCEPT_CALLBACK_PORT",
      callbackServer.identity.primaryPort
    );
    Services.env.set("MOZ_TLS_SERVER_0RTT", "1");
    const started = await asyncStartTLSTestServer(
      "ZeroRttAcceptServer",
      "../../../security/manager/ssl/tests/unit/test_faulty_server"
    );
    if (!started) {
      return;
    }
    gServerStarted = true;

    Services.prefs.setBoolPref("network.http.happy_eyeballs_enabled", true);
    Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
    Services.prefs.setBoolPref("network.ssl_tokens_cache_enabled", true);
    Services.prefs.setBoolPref("network.http.http3.enable", false);
    // Single address to keep the HE race to one HCA.
    Services.prefs.setBoolPref("network.dns.disableIPv6", true);

    override.addIPOverride(kHost, "127.0.0.1");

    registerCleanupFunction(async () => {
      Services.prefs.clearUserPref("network.http.happy_eyeballs_enabled");
      Services.prefs.clearUserPref("network.http.speculative-parallel-limit");
      Services.prefs.clearUserPref("network.ssl_tokens_cache_enabled");
      Services.prefs.clearUserPref("network.http.http3.enable");
      Services.prefs.clearUserPref("network.dns.disableIPv6");
      override.clearOverrides();
      if (callbackServer) {
        await callbackServer.stop();
        callbackServer = null;
      }
    });
  }
);

function fetchResult(url) {
  return new Promise(resolve => {
    let chan = NetUtil.newChannel({
      uri: url,
      loadUsingSystemPrincipal: true,
    }).QueryInterface(Ci.nsIHttpChannel);
    chan.loadFlags =
      Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI | Ci.nsIRequest.LOAD_BYPASS_CACHE;
    chan.asyncOpen({
      onStartRequest() {},
      onDataAvailable(_req, stream, _offset, count) {
        read_stream(stream, count);
      },
      onStopRequest(req, status) {
        let resumed = false;
        try {
          resumed = req.securityInfo.resumed;
        } catch (_e) {}
        resolve({
          ok: Components.isSuccessCode(status),
          status: Components.isSuccessCode(status)
            ? req.QueryInterface(Ci.nsIHttpChannel).responseStatus
            : 0,
          resumed,
        });
      },
      QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
    });
  });
}

add_task(
  {
    skip_if: () =>
      AppConstants.MOZ_SYSTEM_NSS ||
      !gServerStarted ||
      mozinfo.os == "android" ||
      mozinfo.socketprocess_networking,
  },
  async function test_he_h1_0rtt_early_data_rejected_reuses_connection() {
    const url = `https://${kHost}:${kPort}/`;

    let nss = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent);
    await nss.asyncClearSSLExternalAndInternalSessionCache();

    // ── Warm-up: full H1 handshake, PSK ticket written to SSLTokensCache ──
    const wu = await fetchResult(url);
    Assert.ok(wu.ok, "warm-up must succeed");
    Assert.equal(wu.status, 200, "warm-up must return 200");
    Assert.equal(wu.resumed, false, "warm-up must be a fresh handshake");

    // Give NSS time to persist the session ticket, then clear connections
    // so the next request opens a new one (triggering 0-RTT).
    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    await new Promise(r => setTimeout(r, 500));
    Services.obs.notifyObservers(null, "net:cancel-all-connections");
    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    await new Promise(r => setTimeout(r, 200));

    // ── Test: H1 0-RTT, early data rejected (alpnChanged=false) ──────────
    // The server omits SSL_SetAntiReplayContext so NSS rejects early data,
    // but the ALPN stays H1.  ZeroRttHandle::Finish0RTT(restart=1,
    // alpnChanged=0) must fall through to InvokeCallback(NS_OK): the H1
    // connection is still alive and the real transaction is retried on it.
    //
    // resumed=true confirms the PSK ticket was used (TLS session resumed)
    // and the connection was not discarded.  Without the alpnChanged guard,
    // the HET would be closed, the token evicted, and the retry would open
    // a fresh connection with resumed=false.
    const r = await fetchResult(url);
    Assert.ok(r.ok, "request must succeed after 0-RTT early-data rejection");
    Assert.equal(r.status, 200, "request must return 200");
    Assert.equal(
      r.resumed,
      true,
      "PSK must have been used — connection reused after early-data rejection"
    );

    Services.obs.notifyObservers(null, "net:cancel-all-connections");
  }
);

Messung V0.5 in Prozent
C=78 H=100 G=89

¤ Dauer der Verarbeitung: 0.20 Sekunden  (vorverarbeitet am  2026-09-28) ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126438
#Domains=1897691