Skip to content

quic: add experimental ngtcp2 transport#3440

Open
pkorczlab wants to merge 4 commits into
scylladb:masterfrom
scylladb-zpp-2025-seastar-quic:quic
Open

quic: add experimental ngtcp2 transport#3440
pkorczlab wants to merge 4 commits into
scylladb:masterfrom
scylladb-zpp-2025-seastar-quic:quic

Conversation

@pkorczlab

Copy link
Copy Markdown

Add an experimental QUIC transport backed by ngtcp2 and GnuTLS.

The series adds a bundled ngtcp2 build, exposes an ngtcp2::ngtcp2
CMake target, and initializes the ngtcp2 submodule in CI. The DPDK
submodule checkout remains limited to DPDK-enabled builds.

The new API lives under seastar::quic::experimental and provides
client and server endpoints, connections, bidirectional and
unidirectional streams, transport configuration, QUIC errors, and
conversion of bidirectional streams to connected_socket.

Each connection owns its ngtcp2 and TLS state and drives it from a
single async loop that handles received packets, timer expiry, stream
commands, and connection shutdown.

Also add QUIC client/server demos and unit coverage for the public API,
stream lifecycle, flow control, blocked sends, blocked stream opens,
packet handling, close paths, error classification, and socket address
conversion.

pkorczlab and others added 4 commits May 31, 2026 13:35
Add ngtcp2 as a submodule and expose its static GnuTLS build as the
ngtcp2::ngtcp2 CMake target.

The CMake wrapper configures ngtcp2 for a library-only build, links
libngtcp2 with ngtcp2_crypto_gnutls, and exports the source and
generated include directories used by Seastar's QUIC code.

Initialize the ngtcp2 submodule in CI before configuring Seastar, and
keep the DPDK submodule checkout limited to DPDK-enabled builds.

Allow cmake-cooking to delegate project() back to CMake for subprojects
that need their own language and project-version setup.

Co-authored-by: Adam Karaczewski <adam.karaczewski@gmail.com>
Co-authored-by: Kamil Dalidowicz <dalikam748@gmail.com>
Co-authored-by: Piotr Korcz <ptrkorcz@gmail.com>
Co-authored-by: Stanisław Kalewski <fkalewski@gmail.com>
Add an experimental QUIC API implemented on top of ngtcp2 and GnuTLS.

The public interface provides client and server endpoints, connections,
bidirectional and unidirectional streams, transport configuration, QUIC
errors, and conversion of bidirectional streams to connected_socket.

The implementation keeps ngtcp2 and TLS state in per-connection actors.
Public stream operations are translated into transport commands for
stream creation, data writes, receive credit updates, RESET_STREAM,
STOP_SENDING, timers, packet I/O, and connection shutdown.

Co-authored-by: Adam Karaczewski <adam.karaczewski@gmail.com>
Co-authored-by: Kamil Dalidowicz <dalikam748@gmail.com>
Co-authored-by: Piotr Korcz <ptrkorcz@gmail.com>
Co-authored-by: Stanisław Kalewski <fkalewski@gmail.com>
Add quic_client_demo and quic_server_demo.

The server listens on a UDP address, accepts QUIC connections, accepts
streams, and echoes stream data back to the peer. The client connects
to the server, opens a stream, forwards stdin to the stream, prints
received data, and closes the connection on EOF or SIGINT.

The demos cover the application-facing setup for certificate files,
endpoint configuration, connection establishment, stream I/O, and
shutdown.

Co-authored-by: Adam Karaczewski <adam.karaczewski@gmail.com>
Co-authored-by: Kamil Dalidowicz <dalikam748@gmail.com>
Co-authored-by: Piotr Korcz <ptrkorcz@gmail.com>
Co-authored-by: Stanisław Kalewski <fkalewski@gmail.com>
Add unit tests for the experimental QUIC client, server, connection,
stream, and transport helper code.

The tests cover public object defaults, client/server stream exchange,
stream direction handling, accepted-stream delivery, EOF and FIN
handling, resets, STOP_SENDING, connected_socket conversion,
receive-budget accounting, send backpressure, blocked sends, blocked
stream opens, packet receive and drain paths, connection close handling,
error classification, and socket address conversion.

Co-authored-by: Adam Karaczewski <adam.karaczewski@gmail.com>
Co-authored-by: Kamil Dalidowicz <dalikam748@gmail.com>
Co-authored-by: Piotr Korcz <ptrkorcz@gmail.com>
Co-authored-by: Stanisław Kalewski <fkalewski@gmail.com>
Comment thread .gitmodules
Comment on lines +4 to +7

[submodule "ngtcp2"]
path = ngtcp2
url = https://github.com/TusikNusik/ngtcp2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ngtcp2 uses some generic CMake names (ENABLE_STATIC_LIB, ENABLE_SHARED_LIB, etc...) that can collide with seastar CMake names. For this reason there is open PR ngtcp2/ngtcp2#2008. This url points to the PR branch.

The question for maintainers is how to finally maintain this dependency. We could create a fork of ngtcp2 in scylladb organization and put fork the requested change there.

Comment thread cooking.sh
Comment on lines +257 to +260
if (Cooking_USE_CMAKE_PROJECT_COMMAND)
_project (${name} ${ARGN})
endif ()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmake-cooking overrides CMake's function project with its own macro. Ngtcp2's CMakefile doesn't work with this trick so this is a workaround to cmake-cooking. The question is if it is acceptable.

@ewienik ewienik requested a review from avikivity June 2, 2026 15:37
@ewienik

ewienik commented Jun 2, 2026

Copy link
Copy Markdown

@tchaikov FYI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants