"Chame isso de TCP/2. Mais uma vez."
O projeto ngtcp2 é um esforço para implementar o protocolo RFC9000 QUIC.
A documentação on-line está disponível.
Os seguintes endpoints estão disponíveis para testar a implementação do ngtcp2:
https://nghttp2.org:4433
https://nghttp2.org:4434 (requer token de validação de endereço)
https://nghttp2.org (desenvolvido por nghttpx)
Esses endpoints enviam o campo de cabeçalho Alt-Svc aos clientes se ele for acessado via HTTP/1.1 ou HTTP/2 para informar que o HTTP/3 está disponível em UDP 443.
A biblioteca C libngtcp2 em si não depende de nenhuma biblioteca externa. O cliente e o servidor de exemplo são escritos em C++20 e devem ser compilados com os compiladores C++ modernos (por exemplo, clang >= 11.0 ou gcc >= 11.0).
Os seguintes pacotes são necessários para configurar o sistema de compilação:
Para construir fontes no diretório de exemplos, são necessários libev e nghttp3:
Para ativar a compactação de certificado TLS em bsslclient e bsslserver (exemplos de cliente e servidor BoringSSL (aws-lc)), a seguinte biblioteca é necessária:
A biblioteca auxiliar de criptografia ngtcp2 e o cliente e o servidor no diretório de exemplos exigem pelo menos um dos seguintes back-ends TLS:
Ao construir a partir do git, execute o seguinte comando para extrair submódulos:
$ 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
Após a construção bem-sucedida, o executável do cliente e do servidor deve ser encontrado no diretório de exemplos. Eles falam HTTP/3.
$ examples/wsslclient [OPTIONS] < HOST > < PORT > [ < URI > ...]
As opções notáveis são:
-d
, --data=
: Leia os dados de $ examples/wsslserver [OPTIONS] < ADDR > < PORT > < PRIVATE_KEY_FILE > < CERTIFICATE_FILE >
As opções notáveis são:
-V
, --validate-addr
: impõe validação de endereço sem estado. Existem h09wsslclient e h09wsslserver que falam HTTP/0.9. Eles são escritos apenas para executores de interoperabilidade rápida. Eles compartilham as funcionalidades básicas com o cliente e servidor HTTP/3, mas têm menos funções (por exemplo, h09wsslclient não tem capacidade de enviar o corpo da solicitação e h09wsslserver não entende o caminho numérico da solicitação, como /1000).
Para retomar uma sessão, um ticket de sessão e parâmetros de transporte devem ser obtidos do servidor. Primeiro, execute exemplos/wsslclient com as opções --session-file e --tp-file que especificam um caminho para o ticket de sessão e transportam arquivos de parâmetros respectivamente para salvá-los localmente.
Assim que esses arquivos estiverem disponíveis, execute exemplos/wsslclient com os mesmos argumentos novamente. Você verá que a sessão foi retomada em seu log se a retomada for bem-sucedida. A retomada da sessão torna o primeiro pacote de Handshake do servidor muito pequeno porque ele não envia seus certificados.
Para enviar dados 0-RTT, após certificar-se de que a retomada funciona, use a opção -d para especificar um arquivo que contém os dados a serem enviados.
O servidor QUIC pode enviar um token ao cliente após o estabelecimento da conexão. O cliente pode enviar este token na conexão subsequente ao servidor. O servidor verifica o token e, se for bem-sucedido, a validação do endereço é concluída e elimina algumas restrições no servidor que podem acelerar a transferência. Para salvar e/ou carregar um token, use a opção --token-file de exemplos/wsslclient. O arquivo fornecido será substituído se já existir ao armazenar um token.
Para tornar a integração da pilha TLS menos dolorosa, fornecemos uma biblioteca auxiliar de criptografia que oferece as operações básicas de criptografia.
O arquivo de cabeçalho existe no diretório crypto/includes/ngtcp2.
Cada arquivo de biblioteca é criado para um back-end TLS específico. As bibliotecas auxiliares de criptografia disponíveis são:
Como BoringSSL e Picotls são produtos sem versão, testamos apenas sua revisão específica. Consulte a seção Requisitos acima.
Usamos Picotls com OpenSSL como backend criptográfico.
O diretório de exemplos contém cliente e servidor vinculados a essas bibliotecas auxiliares de criptografia e back-ends TLS. Eles só são construídos se sua biblioteca auxiliar de criptografia correspondente for construída:
A biblioteca implementa as seguintes extensões de protocolo QUIC:
O Wireshark pode ser configurado para analisar o tráfego QUIC usando as seguintes etapas:
Defina a variável de ambiente SSLKEYLOGFILE :
$ export SSLKEYLOGFILE=quic_keylog_file
Defina a porta que o QUIC usa
Vá para Preferências->Protocolos->QUIC e defina a porta que o programa escuta. No caso do aplicativo de exemplo, esta seria a porta especificada na linha de comando.
Definir arquivo de log pré-master-secret
Vá para Preferências->Protocolos->TLS e configure o arquivo de log Pre-Master-Secret com o mesmo valor que foi especificado para SSLKEYLOGFILE .
Escolha a interface de rede correta para capturar
Certifique-se de escolher a interface de rede correta para captura. Por exemplo, se estiver usando localhost, escolha a interface de rede de loopback no macOS.
Crie um filtro
Crie um filtro para udp.port e defina a porta para a porta que o aplicativo está escutando. Por exemplo:
udp.port == 7777
A licença do MIT
Copyright (c) contribuidores ngtcp2 de 2016