"Appelez-le TCP/2. Encore une fois."
Le projet ngtcp2 est un effort pour implémenter le protocole RFC9000 QUIC.
Une documentation en ligne est disponible.
Les points de terminaison suivants sont disponibles pour tester l'implémentation de ngtcp2 :
https://nghttp2.org:4433
https://nghttp2.org:4434 (nécessite un jeton de validation d'adresse)
https://nghttp2.org (propulsé par nghttpx)
Ce point de terminaison envoie le champ d'en-tête Alt-Svc aux clients s'il est accessible via HTTP/1.1 ou HTTP/2 pour leur indiquer que HTTP/3 est disponible sur UDP 443.
La bibliothèque C libngtcp2 elle-même ne dépend d'aucune bibliothèque externe. L'exemple de client et le serveur sont écrits en C++20 et doivent être compilés avec les compilateurs C++ modernes (par exemple, clang >= 11.0 ou gcc >= 11.0).
Les packages suivants sont requis pour configurer le système de build :
Pour construire des sources dans le répertoire examples, libev et nghttp3 sont requis :
Pour activer la compression de certificat TLS dans bsslclient et bsslserver (exemples client et serveur BoringSSL (aws-lc), la bibliothèque suivante est requise :
La bibliothèque d'assistance de chiffrement ngtcp2, ainsi que le client et le serveur dans le répertoire d'exemples nécessitent au moins l'un des backends TLS suivants :
Lors de la construction à partir de git, exécutez la commande suivante pour extraire les sous-modules :
$ 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
Une fois la construction réussie, les exécutables client et serveur devraient être trouvés dans le répertoire des exemples. Ils parlent HTTP/3.
$ examples/wsslclient [OPTIONS] < HOST > < PORT > [ < URI > ...]
Les options notables sont :
-d
, --data=
: lit les données de $ examples/wsslserver [OPTIONS] < ADDR > < PORT > < PRIVATE_KEY_FILE > < CERTIFICATE_FILE >
Les options notables sont :
-V
, --validate-addr
: Applique la validation d'adresse sans état. Il existe h09wsslclient et h09wsslserver qui parlent HTTP/0.9. Ils sont écrits uniquement pour quic-interop-runner. Ils partagent les fonctionnalités de base avec le client et le serveur HTTP/3 mais ont moins de fonctions (par exemple, h09wsslclient n'a pas la capacité d'envoyer le corps de la requête et h09wsslserver ne comprend pas le chemin de requête numérique, comme /1000).
Afin de reprendre une session, un ticket de session et des paramètres de transport doivent être récupérés depuis le serveur. Tout d’abord, exécutez examples/wsslclient avec les options --session-file et --tp-file qui spécifient respectivement un chemin d’accès au ticket de session et aux fichiers de paramètres de transport pour les enregistrer localement.
Une fois ces fichiers disponibles, exécutez à nouveau examples/wsslclient avec les mêmes arguments. Vous verrez que la session est reprise dans votre journal si la reprise réussit. La reprise de la session rend le premier paquet Handshake du serveur assez petit car il n'envoie pas ses certificats.
Pour envoyer des données 0-RTT, après vous être assuré que la reprise fonctionne, utilisez l'option -d pour spécifier un fichier contenant les données à envoyer.
Le serveur QUIC peut envoyer un jeton au client une fois la connexion établie. Le client peut envoyer ce jeton lors d'une connexion ultérieure au serveur. Le serveur vérifie le jeton et s'il réussit, la validation de l'adresse se termine et lève certaines restrictions sur le serveur, ce qui pourrait accélérer le transfert. Afin d'enregistrer et/ou de charger un jeton, utilisez l'option --token-file de examples/wsslclient. Le fichier donné est écrasé s'il existe déjà lors du stockage d'un jeton.
Afin de rendre l'intégration de la pile TLS moins pénible, nous fournissons une bibliothèque d'assistance de chiffrement qui propose les opérations de chiffrement de base.
Le fichier d'en-tête existe dans le répertoire crypto/includes/ngtcp2.
Chaque fichier de bibliothèque est conçu pour un backend TLS particulier. Les bibliothèques d'assistance de chiffrement disponibles sont :
Comme BoringSSL et Picotls sont des produits non versionnés, nous avons uniquement testé leur révision particulière. Voir la section Exigences ci-dessus.
Nous utilisons Picotls avec OpenSSL comme backend crypto.
Le répertoire d'exemples contient le client et le serveur liés à ces bibliothèques d'assistance de chiffrement et à ces backends TLS. Ils ne sont construits que si leur bibliothèque d'assistance cryptographique correspondante est construite :
La bibliothèque implémente les extensions de protocole QUIC suivantes :
Wireshark peut être configuré pour analyser le trafic QUIC en suivant les étapes suivantes :
Définissez la variable d'environnement SSLKEYLOGFILE :
$ export SSLKEYLOGFILE=quic_keylog_file
Définir le port utilisé par QUIC
Allez dans Préférences->Protocoles->QUIC et définissez le port que le programme écoute. Dans le cas de l'exemple d'application, il s'agirait du port spécifié sur la ligne de commande.
Définir le fichier journal pré-maître-secret
Accédez à Preferences->Protocols->TLS et définissez le fichier journal Pre-Master-Secret sur la même valeur que celle spécifiée pour SSLKEYLOGFILE .
Choisissez la bonne interface réseau pour la capture
Assurez-vous de choisir la bonne interface réseau pour la capture. Par exemple, si vous utilisez localhost, choisissez l'interface réseau de bouclage sur Macos.
Créer un filtre
Créez un filtre pour udp.port et définissez le port sur le port que l'application écoute. Par exemple:
udp.port == 7777
La licence MIT
Copyright (c) 2016 Contributeurs ngtcp2