«Назовем это TCP/2. Еще раз».
Проект ngtcp2 — это попытка реализовать протокол QUIC RFC9000.
Доступна онлайн-документация.
Для опробования реализации ngtcp2 доступны следующие конечные точки:
https://nghttp2.org:4433
https://nghttp2.org:4434 (требуется токен проверки адреса)
https://nghttp2.org (при поддержке nghttpx)
Эта конечная точка отправляет клиентам поле заголовка Alt-Svc, если доступ к нему осуществляется через HTTP/1.1 или HTTP/2, чтобы сообщить им, что HTTP/3 доступен по UDP 443.
Сама библиотека C libngtcp2 не зависит ни от каких внешних библиотек. Примеры клиента и сервера написаны на C++20 и должны компилироваться современными компиляторами C++ (например, clang >= 11.0 или gcc >= 11.0).
Для настройки системы сборки необходимы следующие пакеты:
Для сборки исходников в каталоге примеров необходимы libev и nghttp3:
Чтобы включить сжатие сертификатов TLS в bsslclient и bsslserver (примеры клиента и сервера BoringSSL (aws-lc)), требуется следующая библиотека:
Вспомогательная библиотека шифрования ngtcp2, а также клиент и сервер в каталоге примеров требуют хотя бы одного из следующих бэкэндов TLS:
При сборке из git выполните следующую команду, чтобы извлечь подмодули:
$ 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
После успешной сборки исполняемый файл клиента и сервера должен находиться в каталоге примеров. Они говорят HTTP/3.
$ examples/wsslclient [OPTIONS] < HOST > < PORT > [ < URI > ...]
Примечательными вариантами являются:
-d
, --data=
: прочитать данные из $ examples/wsslserver [OPTIONS] < ADDR > < PORT > < PRIVATE_KEY_FILE > < CERTIFICATE_FILE >
Примечательными вариантами являются:
-V
, --validate-addr
: обеспечить проверку адреса без сохранения состояния. Существуют h09wsslclient и h09wsslserver, поддерживающие HTTP/0.9. Они написаны только для quic-interop-runner. Они разделяют базовые функции с клиентом и сервером HTTP/3, но имеют меньше функций (например, h09wsslclient не имеет возможности отправлять тело запроса, а h09wsslserver не понимает числовой путь запроса, например /1000).
Чтобы возобновить сеанс, билет сеанса и параметры транспорта должны быть получены с сервера. Сначала запустите example/wsslclient с параметрами --session-file и --tp-file, которые указывают путь к билету сеанса, и файлы параметров транспорта соответственно, чтобы сохранить их локально.
Как только эти файлы станут доступны, снова запустите example/wsslclient с теми же аргументами. Если возобновление будет успешным, вы увидите, что сеанс возобновится в вашем журнале. Возобновление сеанса делает первый пакет рукопожатия сервера довольно маленьким, поскольку он не отправляет свои сертификаты.
Чтобы отправить данные 0-RTT, убедившись, что возобновление работает, используйте опцию -d, чтобы указать файл, содержащий данные для отправки.
Сервер QUIC может отправить токен клиенту после установления соединения. Клиент может отправить этот токен при последующем подключении к серверу. Сервер проверяет токен, и если проверка прошла успешно, проверка адреса завершается и снимаются некоторые ограничения на сервере, которые могут ускорить передачу. Чтобы сохранить и/или загрузить токен, используйте опцию --token-file в example/wsslclient. Данный файл перезаписывается, если он уже существует при сохранении токена.
Чтобы сделать интеграцию стека TLS менее болезненной, мы предоставляем вспомогательную библиотеку шифрования, которая предлагает основные криптографические операции.
Заголовочный файл находится в каталоге crypto/includes/ngtcp2.
Каждый файл библиотеки создан для определенного бэкэнда TLS. Доступные вспомогательные библиотеки шифрования:
Поскольку BoringSSL и Picotls являются неверсированными продуктами, мы тестировали только их конкретную версию. См. раздел «Требования» выше.
Мы используем Picotls с OpenSSL в качестве криптографического бэкэнда.
Каталог примеров содержит клиент и сервер, которые связаны с этими вспомогательными библиотеками шифрования и серверными модулями TLS. Они создаются только в том случае, если построена соответствующая им вспомогательная библиотека шифрования:
В библиотеке реализованы следующие расширения протокола QUIC:
Wireshark можно настроить для анализа трафика QUIC, выполнив следующие действия:
Установите переменную среды SSLKEYLOGFILE :
$ export SSLKEYLOGFILE=quic_keylog_file
Установите порт, который использует QUIC
Перейдите в «Настройки->Протоколы->QUIC» и установите порт, который прослушивает программа. В случае примера приложения это будет порт, указанный в командной строке.
Установить файл журнала Pre-Master-Secret
Перейдите в «Настройки->Протоколы->TLS» и установите для файла журнала Pre-Master-Secret то же значение, которое было указано для SSLKEYLOGFILE .
Выберите правильный сетевой интерфейс для захвата
Убедитесь, что вы выбрали правильный сетевой интерфейс для захвата. Например, если вы используете localhost, выберите сетевой интерфейс обратной связи на Macos.
Создать фильтр
Создайте фильтр для udp.port и установите порт, который прослушивает приложение. Например:
udp.порт == 7777
Лицензия MIT
Авторские права (c) 2016 участников ngtcp2