„Nennen Sie es TCP/2. Noch einmal.“
Das Projekt ngtcp2 ist ein Versuch, das RFC9000-QUIC-Protokoll zu implementieren.
Eine Online-Dokumentation ist verfügbar.
Die folgenden Endpunkte stehen zum Ausprobieren der ngtcp2-Implementierung zur Verfügung:
https://nghttp2.org:4433
https://nghttp2.org:4434 (erfordert Adressvalidierungstoken)
https://nghttp2.org (unterstützt von nghttpx)
Dieser Endpunkt sendet das Alt-Svc-Header-Feld an Clients, wenn über HTTP/1.1 oder HTTP/2 darauf zugegriffen wird, um ihnen mitzuteilen, dass HTTP/3 unter UDP 443 verfügbar ist.
Die C-Bibliothek libngtcp2 selbst ist nicht von externen Bibliotheken abhängig. Der Beispiel-Client und -Server sind in C++20 geschrieben und sollten mit den modernen C++-Compilern kompiliert werden (z. B. clang >= 11.0 oder gcc >= 11.0).
Zur Konfiguration des Build-Systems sind folgende Pakete erforderlich:
Um Quellen im Beispielverzeichnis zu erstellen, sind libev und nghttp3 erforderlich:
Um die TLS-Zertifikatkomprimierung in bsslclient und bsslserver (BoringSSL (aws-lc)-Beispielclient und -server) zu aktivieren, ist die folgende Bibliothek erforderlich:
Die ngtcp2-Krypto-Hilfsbibliothek sowie Client und Server im Beispielverzeichnis erfordern mindestens eines der folgenden TLS-Backends:
Führen Sie beim Build aus Git den folgenden Befehl aus, um Submodule abzurufen:
$ git submodule update --init
$ git clone --depth 1 -b v5.7.4-stable https://github.com/wolfSSL/wolfssl
$ cd wolfssl
$ autoreconf -i
$ # For wolfSSL < v5.6.6, append --enable-quic.
$ ./configure --prefix= $PWD /build
--enable-all --enable-aesni --enable-harden --enable-keylog-export
--disable-ech
$ make -j $( nproc )
$ make install
$ cd ..
$ git clone --recursive https://github.com/ngtcp2/nghttp3
$ cd nghttp3
$ autoreconf -i
$ ./configure --prefix= $PWD /build --enable-lib-only
$ make -j $( nproc ) check
$ make install
$ cd ..
$ git clone --recursive https://github.com/ngtcp2/ngtcp2
$ cd ngtcp2
$ autoreconf -i
$ # For Mac users who have installed libev with MacPorts, append
$ # LIBEV_CFLAGS="-I/opt/local/include" LIBEV_LIBS="-L/opt/local/lib -lev"
$ ./configure PKG_CONFIG_PATH= $PWD /../wolfssl/build/lib/pkgconfig: $PWD /../nghttp3/build/lib/pkgconfig
--with-wolfssl
$ make -j $( nproc ) check
$ git clone https://boringssl.googlesource.com/boringssl
$ cd boringssl
$ git checkout 83fc0d94d7040544480d42db01554f2421cfc081
$ cmake -B build -DCMAKE_POSITION_INDEPENDENT_CODE=ON
$ make -j $( nproc ) -C build
$ cd ..
$ git clone --recursive https://github.com/ngtcp2/nghttp3
$ cd nghttp3
$ autoreconf -i
$ ./configure --prefix= $PWD /build --enable-lib-only
$ make -j $( nproc ) check
$ make install
$ cd ..
$ git clone --recursive https://github.com/ngtcp2/ngtcp2
$ cd ngtcp2
$ autoreconf -i
$ # For Mac users who have installed libev with MacPorts, append
$ # LIBEV_CFLAGS="-I/opt/local/include" LIBEV_LIBS="-L/opt/local/lib -lev"
$ ./configure PKG_CONFIG_PATH= $PWD /../nghttp3/build/lib/pkgconfig
BORINGSSL_LIBS= " -L $PWD /../boringssl/build/ssl -lssl -L $PWD /../boringssl/build/crypto -lcrypto "
BORINGSSL_CFLAGS= " -I $PWD /../boringssl/include "
--with-boringssl
$ make -j $( nproc ) check
$ git clone --depth 1 -b v1.39.0 https://github.com/aws/aws-lc
$ cd aws-lc
$ cmake -B build -DDISABLE_GO=ON
$ make -j $( nproc ) -C build
$ cd ..
$ git clone --recursive https://github.com/ngtcp2/nghttp3
$ cd nghttp3
$ autoreconf -i
$ ./configure --prefix= $PWD /build --enable-lib-only
$ make -j $( nproc ) check
$ make install
$ cd ..
$ git clone --recursive https://github.com/ngtcp2/ngtcp2
$ cd ngtcp2
$ autoreconf -i
$ # For Mac users who have installed libev with MacPorts, append
$ # LIBEV_CFLAGS="-I/opt/local/include" LIBEV_LIBS="-L/opt/local/lib -lev"
$ ./configure PKG_CONFIG_PATH= $PWD /../nghttp3/build/lib/pkgconfig
BORINGSSL_CFLAGS= " -I $PWD /../aws-lc/include "
BORINGSSL_LIBS= " -L $PWD /../aws-lc/build/ssl -lssl -L $PWD /../aws-lc/build/crypto -lcrypto "
--with-boringssl
$ make -j $( nproc ) check
$ git clone --depth 1 -b v4.0.0 https://github.com/libressl/portable.git libressl
$ cd libressl
$ # Workaround autogen.sh failure
$ export LIBRESSL_GIT_OPTIONS= " -b libressl-v4.0.0 "
$ ./autogen.sh
$ ./configure --prefix= $PWD /build
$ make -j $( nproc ) install
$ cd ..
$ git clone --recursive https://github.com/ngtcp2/nghttp3
$ cd nghttp3
$ autoreconf -i
$ ./configure --prefix= $PWD /build --enable-lib-only
$ make -j $( nproc ) check
$ make install
$ cd ..
$ git clone --recursive https://github.com/ngtcp2/ngtcp2
$ cd ngtcp2
$ autoreconf -i
$ # For Mac users who have installed libev with MacPorts, append
$ # LIBEV_CFLAGS="-I/opt/homebrew/Cellar/libev/4.33/include" LIBEV_LIBS="-L/opt/homebrew/Cellar/libev/4.33/lib -lev"
$ ./configure PKG_CONFIG_PATH= $PWD /../nghttp3/build/lib/pkgconfig: $PWD /../libressl/build/lib/pkgconfig
$ make -j $( nproc ) check
Nach erfolgreicher Erstellung sollten sich die ausführbaren Client- und Serverdateien im Beispielverzeichnis befinden. Sie sprechen HTTP/3.
$ examples/wsslclient [OPTIONS] < HOST > < PORT > [ < URI > ...]
Die bemerkenswerten Optionen sind:
-d
, --data=
: Daten aus $ examples/wsslserver [OPTIONS] < ADDR > < PORT > < PRIVATE_KEY_FILE > < CERTIFICATE_FILE >
Die bemerkenswerten Optionen sind:
-V
, --validate-addr
: Zustandslose Adressvalidierung erzwingen. Es gibt h09wsslclient und h09wsslserver, die HTTP/0.9 sprechen. Sie sind nur für Quick-Interop-Runner geschrieben. Sie teilen die Grundfunktionen mit HTTP/3-Client und -Server, verfügen jedoch über weniger Funktionen (z. B. kann h09wsslclient keinen Anforderungstext senden, und h09wsslserver versteht keinen numerischen Anforderungspfad wie /1000).
Um eine Sitzung fortzusetzen, müssen ein Sitzungsticket und Transportparameter vom Server abgerufen werden. Führen Sie zunächst examples/wsslclient mit den Optionen --session-file und --tp-file aus, die einen Pfad zum Sitzungsticket angeben, bzw. transportieren Sie Parameterdateien, um sie lokal zu speichern.
Sobald diese Dateien verfügbar sind, führen Sie „examples/wsslclient“ erneut mit denselben Argumenten aus. Wenn die Wiederaufnahme erfolgreich ist, sehen Sie in Ihrem Protokoll, dass die Sitzung fortgesetzt wird. Durch die Wiederaufnahme der Sitzung wird das erste Handshake-Paket des Servers ziemlich klein, da er seine Zertifikate nicht sendet.
Um 0-RTT-Daten zu senden, nachdem Sie sichergestellt haben, dass die Wiederaufnahme funktioniert, verwenden Sie die Option -d, um eine Datei anzugeben, die die zu sendenden Daten enthält.
Der QUIC-Server sendet möglicherweise ein Token an den Client, nachdem die Verbindung hergestellt wurde. Der Client kann dieses Token bei einer späteren Verbindung zum Server senden. Der Server überprüft das Token. Wenn dies erfolgreich ist, wird die Adressvalidierung abgeschlossen und einige Einschränkungen auf dem Server aufgehoben, was die Übertragung beschleunigen könnte. Um ein Token zu speichern und/oder zu laden, verwenden Sie die Option --token-file von examples/wsslclient. Die angegebene Datei wird überschrieben, wenn sie beim Speichern eines Tokens bereits vorhanden ist.
Um die TLS-Stack-Integration weniger mühsam zu gestalten, stellen wir eine Krypto-Hilfsbibliothek zur Verfügung, die die grundlegenden Krypto-Operationen bietet.
Die Header-Datei befindet sich im Verzeichnis crypto/includes/ngtcp2.
Jede Bibliotheksdatei wird für ein bestimmtes TLS-Backend erstellt. Die verfügbaren Krypto-Hilfsbibliotheken sind:
Da es sich bei BoringSSL und Picotls um nicht versionierte Produkte handelt, haben wir nur ihre jeweilige Revision getestet. Siehe Abschnitt „Anforderungen“ oben.
Wir verwenden Picotls mit OpenSSL als Krypto-Backend.
Das Beispielverzeichnis enthält Client und Server, die mit diesen Krypto-Hilfsbibliotheken und TLS-Backends verknüpft sind. Sie werden nur erstellt, wenn ihre entsprechende Krypto-Helper-Bibliothek erstellt wird:
Die Bibliothek implementiert die folgenden QUIC-Protokollerweiterungen:
Wireshark kann mithilfe der folgenden Schritte für die Analyse des QUIC-Verkehrs konfiguriert werden:
Legen Sie die Umgebungsvariable SSLKEYLOGFILE fest:
$ export SSLKEYLOGFILE=quic_keylog_file
Legen Sie den Port fest, den QUIC verwendet
Gehen Sie zu Einstellungen->Protokolle->QUIC und legen Sie den Port fest, den das Programm abhört. Im Falle der Beispielanwendung wäre dies der in der Kommandozeile angegebene Port.
Legen Sie die Protokolldatei „Pre-Master-Secret“ fest
Gehen Sie zu Einstellungen->Protokolle->TLS und setzen Sie die Pre-Master-Secret-Protokolldatei auf denselben Wert, der für SSLKEYLOGFILE angegeben wurde.
Wählen Sie die richtige Netzwerkschnittstelle für die Erfassung
Stellen Sie sicher, dass Sie die richtige Netzwerkschnittstelle für die Aufnahme auswählen. Wenn Sie beispielsweise localhost verwenden, wählen Sie die Loopback- Netzwerkschnittstelle auf MacOS.
Erstellen Sie einen Filter
Erstellen Sie einen Filter für udp.port und legen Sie den Port auf den Port fest, den die Anwendung überwacht. Zum Beispiel:
udp.port == 7777
Die MIT-Lizenz
Copyright (c) 2016 ngtcp2-Mitwirkende