Compare commits
5 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21d2911187 | ||
|
|
44bb34dff5 | ||
|
|
1f34618759 | ||
|
|
ff62ea6c8a | ||
|
|
0b69672e98 |
3 changed files with 195 additions and 59 deletions
|
|
@ -1,12 +1,16 @@
|
|||
%global upstream_sources 0 1
|
||||
%global pgp_signature_sources 1
|
||||
|
||||
%bcond CHECK 1
|
||||
|
||||
Name: ngtcp2
|
||||
Version: 1.21.0
|
||||
Version: 1.25.0
|
||||
Release: %autorelease
|
||||
Summary: Implementation of RFC 9000 QUIC protocol
|
||||
|
||||
License: MIT
|
||||
URL: https://github.com/ngtcp2/ngtcp2
|
||||
VCS: git:%{url}.git
|
||||
Source0: %{url}/releases/download/v%{version}/%{name}-%{version}.tar.xz
|
||||
Source1: %{url}/releases/download/v%{version}/%{name}-%{version}.tar.xz.asc
|
||||
Source2: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xf4f3b91474d1eb29889bd0ef7e8403d5d673c366#/tatsuhiro-t.asc
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ to build QUIC application you have to choose one of them. Here is the
|
|||
list of TLS stacks which are supposed to provide such interface and
|
||||
for which we provide crypto helper libraries:
|
||||
|
||||
* `quictls <https://github.com/quictls/openssl>`_
|
||||
* `quictls <https://github.com/quictls/openssl>`_ (deprecated)
|
||||
* GnuTLS
|
||||
* BoringSSL
|
||||
* aws-lc
|
||||
|
|
@ -56,8 +56,8 @@ callback functions must be set:
|
|||
* :member:`recv_retry <ngtcp2_callbacks.recv_retry>`:
|
||||
`ngtcp2_crypto_recv_retry_cb()` can be passed directly.
|
||||
* :member:`rand <ngtcp2_callbacks.rand>`
|
||||
* :member:`get_new_connection_id
|
||||
<ngtcp2_callbacks.get_new_connection_id>`
|
||||
* :member:`get_new_connection_id2
|
||||
<ngtcp2_callbacks.get_new_connection_id2>`
|
||||
* :member:`update_key <ngtcp2_callbacks.update_key>`:
|
||||
`ngtcp2_crypto_update_key_cb()` can be passed directly.
|
||||
* :member:`delete_crypto_aead_ctx
|
||||
|
|
@ -67,9 +67,9 @@ callback functions must be set:
|
|||
<ngtcp2_callbacks.delete_crypto_cipher_ctx>`:
|
||||
`ngtcp2_crypto_delete_crypto_cipher_ctx_cb()` can be passed
|
||||
directly.
|
||||
* :member:`get_path_challenge_data
|
||||
<ngtcp2_callbacks.get_path_challenge_data>`:
|
||||
`ngtcp2_crypto_get_path_challenge_data_cb()` can be passed directly.
|
||||
* :member:`get_path_challenge_data2
|
||||
<ngtcp2_callbacks.get_path_challenge_data2>`:
|
||||
`ngtcp2_crypto_get_path_challenge_data2_cb()` can be passed directly.
|
||||
* :member:`version_negotiation
|
||||
<ngtcp2_callbacks.version_negotiation>`:
|
||||
`ngtcp2_crypto_version_negotiation_cb()` can be passed directly.
|
||||
|
|
@ -88,8 +88,8 @@ For server application, the following callback functions must be set:
|
|||
* :member:`hp_mask <ngtcp2_callbacks.hp_mask>`:
|
||||
`ngtcp2_crypto_hp_mask_cb()` can be passed directly.
|
||||
* :member:`rand <ngtcp2_callbacks.rand>`
|
||||
* :member:`get_new_connection_id
|
||||
<ngtcp2_callbacks.get_new_connection_id>`
|
||||
* :member:`get_new_connection_id2
|
||||
<ngtcp2_callbacks.get_new_connection_id2>`
|
||||
* :member:`update_key <ngtcp2_callbacks.update_key>`:
|
||||
`ngtcp2_crypto_update_key_cb()` can be passed directly.
|
||||
* :member:`delete_crypto_aead_ctx
|
||||
|
|
@ -99,9 +99,9 @@ For server application, the following callback functions must be set:
|
|||
<ngtcp2_callbacks.delete_crypto_cipher_ctx>`:
|
||||
`ngtcp2_crypto_delete_crypto_cipher_ctx_cb()` can be passed
|
||||
directly.
|
||||
* :member:`get_path_challenge_data
|
||||
<ngtcp2_callbacks.get_path_challenge_data>`:
|
||||
`ngtcp2_crypto_get_path_challenge_data_cb()` can be passed directly.
|
||||
* :member:`get_path_challenge_data2
|
||||
<ngtcp2_callbacks.get_path_challenge_data2>`:
|
||||
`ngtcp2_crypto_get_path_challenge_data2_cb()` can be passed directly.
|
||||
* :member:`version_negotiation
|
||||
<ngtcp2_callbacks.version_negotiation>`:
|
||||
`ngtcp2_crypto_version_negotiation_cb()` can be passed directly.
|
||||
|
|
@ -153,6 +153,8 @@ path. An application must provide actual path to the API function to
|
|||
tell the library where a packet comes from. The "write" API function
|
||||
takes path parameter and fills it to which the packet should be sent.
|
||||
|
||||
.. _tls-integration:
|
||||
|
||||
TLS integration
|
||||
---------------
|
||||
|
||||
|
|
@ -164,34 +166,7 @@ The most of the TLS work is done by the callback functions passed to
|
|||
application in order to make TLS integration work. We have a set of
|
||||
helper functions to make it easier for applications to configure TLS
|
||||
stack object to work with QUIC and ngtcp2. They are specific to each
|
||||
supported TLS stack:
|
||||
|
||||
- quictls
|
||||
|
||||
* `ngtcp2_crypto_quictls_configure_client_context`
|
||||
* `ngtcp2_crypto_quictls_configure_server_context`
|
||||
|
||||
- BoringSSL and aws-lc
|
||||
|
||||
* `ngtcp2_crypto_boringssl_configure_client_context`
|
||||
* `ngtcp2_crypto_boringssl_configure_server_context`
|
||||
|
||||
- GnuTLS
|
||||
|
||||
* `ngtcp2_crypto_gnutls_configure_client_session`
|
||||
* `ngtcp2_crypto_gnutls_configure_server_session`
|
||||
|
||||
- Picotls
|
||||
|
||||
* `ngtcp2_crypto_picotls_configure_client_context`
|
||||
* `ngtcp2_crypto_picotls_configure_server_context`
|
||||
* `ngtcp2_crypto_picotls_configure_client_session`
|
||||
* `ngtcp2_crypto_picotls_configure_server_session`
|
||||
|
||||
- wolfSSL
|
||||
|
||||
* `ngtcp2_crypto_wolfssl_configure_client_context`
|
||||
* `ngtcp2_crypto_wolfssl_configure_server_context`
|
||||
supported TLS stack.
|
||||
|
||||
They make the minimal QUIC specific changes to TLS stack object. See
|
||||
the ngtcp2 crypto API header files for each supported TLS stack. In
|
||||
|
|
@ -201,6 +176,138 @@ object, and its :member:`ngtcp2_crypto_conn_ref.get_conn` must point
|
|||
to a function which returns :type:`ngtcp2_conn` of the underlying QUIC
|
||||
connection.
|
||||
|
||||
quictls
|
||||
~~~~~~~
|
||||
|
||||
The ``SSL_CTX`` object should be configured with one of the following
|
||||
functions:
|
||||
|
||||
* `ngtcp2_crypto_quictls_configure_client_context`
|
||||
* `ngtcp2_crypto_quictls_configure_server_context`
|
||||
|
||||
The ``SSL`` should be set as the TLS native handle for the connection
|
||||
using `ngtcp2_conn_set_tls_native_handle`.
|
||||
|
||||
:type:`ngtcp2_crypto_conn_ref` must be set as a user data in ``SSL``
|
||||
object via ``SSL_set_app_data``.
|
||||
|
||||
`ngtcp2_crypto_recv_crypto_data_cb` treats the following errors from
|
||||
`ngtcp2_crypto_read_write_crypto_data` as success:
|
||||
|
||||
- :macro:`NGTCP2_CRYPTO_QUICTLS_ERR_TLS_WANT_X509_LOOKUP`
|
||||
- :macro:`NGTCP2_CRYPTO_QUICTLS_ERR_TLS_WANT_CLIENT_HELLO_CB`
|
||||
|
||||
To continue the handshake, call `ngtcp2_conn_continue_handshake`.
|
||||
|
||||
BoringSSL and aws-lc
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``SSL_CTX`` object should be configured with one of the following
|
||||
functions:
|
||||
|
||||
* `ngtcp2_crypto_boringssl_configure_client_context`
|
||||
* `ngtcp2_crypto_boringssl_configure_server_context`
|
||||
|
||||
The ``SSL`` should be set as the TLS native handle for the connection
|
||||
using `ngtcp2_conn_set_tls_native_handle`.
|
||||
|
||||
:type:`ngtcp2_crypto_conn_ref` must be set as a user data in ``SSL``
|
||||
object via ``SSL_set_app_data``.
|
||||
|
||||
`ngtcp2_crypto_read_write_crypto_data` treats the following errors
|
||||
from ``SSL_do_handshake`` as success in order to support the
|
||||
asynchronous operations:
|
||||
|
||||
- ``SSL_ERROR_WANT_X509_LOOKUP``
|
||||
- ``SSL_ERROR_WANT_PRIVATE_KEY_OPERATION``
|
||||
- ``SSL_ERROR_WANT_CERTIFICATE_VERIFY``
|
||||
|
||||
To continue the handshake, call `ngtcp2_conn_continue_handshake`.
|
||||
|
||||
GnuTLS
|
||||
~~~~~~
|
||||
|
||||
The ``gnutls_session_t`` object should be configured with one of the
|
||||
following functions:
|
||||
|
||||
* `ngtcp2_crypto_gnutls_configure_client_session`
|
||||
* `ngtcp2_crypto_gnutls_configure_server_session`
|
||||
|
||||
The ``gnutls_session_t`` should be set as the TLS native handle for
|
||||
the connection using `ngtcp2_conn_set_tls_native_handle`.
|
||||
|
||||
:type:`ngtcp2_crypto_conn_ref` must be set as a user data in
|
||||
``gnutls_session_t`` object via ``gnutls_session_set_ptr``.
|
||||
|
||||
Picotls
|
||||
~~~~~~~
|
||||
|
||||
The ``ptls_context_t`` object should be configured with one of the
|
||||
following functions:
|
||||
|
||||
* `ngtcp2_crypto_picotls_configure_client_context`
|
||||
* `ngtcp2_crypto_picotls_configure_server_context`
|
||||
|
||||
For each TLS session, create :type:`ngtcp2_crypto_picotls_ctx` object.
|
||||
It should be initialized by `ngtcp2_crypto_picotls_ctx_init`, and
|
||||
configured with one of the following functions:
|
||||
|
||||
* `ngtcp2_crypto_picotls_configure_client_session`
|
||||
* `ngtcp2_crypto_picotls_configure_server_session`
|
||||
|
||||
The :type:`ngtcp2_crypto_picotls_ctx` should be set as the TLS native
|
||||
handle for the connection using `ngtcp2_conn_set_tls_native_handle`.
|
||||
|
||||
:type:`ngtcp2_crypto_conn_ref` must be set as a user data in
|
||||
``ptls_t`` object inside :type:`ngtcp2_crypto_picotls_ctx` via
|
||||
``ptls_get_data_ptr``.
|
||||
|
||||
wolfSSL
|
||||
~~~~~~~
|
||||
|
||||
The ``WOLFSSL_CTX`` object should be configured with one of the
|
||||
following functions:
|
||||
|
||||
* `ngtcp2_crypto_wolfssl_configure_client_context`
|
||||
* `ngtcp2_crypto_wolfssl_configure_server_context`
|
||||
|
||||
The ``WOLFSSL`` should be set as the TLS native handle for the
|
||||
connection using `ngtcp2_conn_set_tls_native_handle`.
|
||||
|
||||
:type:`ngtcp2_crypto_conn_ref` must be set as a user data in
|
||||
``WOLFSSL`` object via ``wolfSSL_set_app_data``.
|
||||
|
||||
OpenSSL
|
||||
~~~~~~~
|
||||
|
||||
The ``SSL`` object should be configured with one of the following
|
||||
functions:
|
||||
|
||||
* `ngtcp2_crypto_ossl_configure_client_session`
|
||||
* `ngtcp2_crypto_ossl_configure_server_session`
|
||||
|
||||
For each TLS session, create :type:`ngtcp2_crypto_ossl_ctx` via
|
||||
`ngtcp2_crypto_ossl_ctx_new`. It should be set as the TLS native
|
||||
handle for the connection using `ngtcp2_conn_set_tls_native_handle`.
|
||||
|
||||
:type:`ngtcp2_crypto_conn_ref` must be set as a user data in
|
||||
``SSL`` object via ``SSL_set_app_data``.
|
||||
|
||||
The application must make sure that :type:`ngtcp2_conn` is kept alive
|
||||
until the ``SSL`` object is freed by ``SSL_free``, or it must call
|
||||
``SSL_set_app_data(ssl, NULL)`` before calling ``SSL_free``.
|
||||
|
||||
`ngtcp2_crypto_recv_crypto_data_cb` treats the following errors from
|
||||
`ngtcp2_crypto_read_write_crypto_data` as success:
|
||||
|
||||
- :macro:`NGTCP2_CRYPTO_OSSL_ERR_TLS_WANT_X509_LOOKUP`
|
||||
- :macro:`NGTCP2_CRYPTO_OSSL_ERR_TLS_WANT_CLIENT_HELLO_CB`
|
||||
|
||||
To continue the handshake, call `ngtcp2_conn_continue_handshake`.
|
||||
|
||||
Configuring TLS stack yourself
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you do not use the above helper functions, you need to generate and
|
||||
install keys to :type:`ngtcp2_conn`, and pass handshake messages to
|
||||
:type:`ngtcp2_conn` as well. When TLS stack generates new secrets,
|
||||
|
|
@ -210,6 +317,24 @@ they have to be installed to :type:`ngtcp2_conn` by calling
|
|||
new crypto data to send, they must be passed to :type:`ngtcp2_conn` by
|
||||
calling `ngtcp2_conn_submit_crypto_data()`.
|
||||
|
||||
Continue the interrupted TLS handshake
|
||||
--------------------------------------
|
||||
|
||||
Some TLS stacks offer the capability to interrupt TLS handshake to
|
||||
perform certain operations asynchronously (e.g., private key signing,
|
||||
certificate lookup). In general, ngtcp2 does not need to know whether
|
||||
the TLS handshake is interrupted or not. In most cases, if the
|
||||
interruption happens, the TLS handshake function returns the special
|
||||
error codes. For supported operations, ngtcp2 crypto helper library
|
||||
treats them as success (see the above `TLS integration`_ section,
|
||||
`ngtcp2_crypto_read_write_crypto_data`, and
|
||||
`ngtcp2_crypto_recv_crypto_data_cb`). The interrupted handshake is
|
||||
not restarted automatically. To continue the handshake, application
|
||||
should call `ngtcp2_conn_continue_handshake`.
|
||||
|
||||
QUIC handshake completion
|
||||
-------------------------
|
||||
|
||||
When QUIC handshake is completed,
|
||||
:member:`ngtcp2_callbacks.handshake_completed` callback function is
|
||||
called. The local and remote endpoint independently declare handshake
|
||||
|
|
@ -253,13 +378,13 @@ stream. For unidirectional stream, call
|
|||
to send stream data.
|
||||
|
||||
An application should pace sending packets.
|
||||
`ngtcp2_conn_get_send_quantum()` returns the number of bytes that can
|
||||
`ngtcp2_conn_get_send_quantum2()` returns the number of bytes that can
|
||||
be sent without packet spacing. After one or more calls of
|
||||
`ngtcp2_conn_writev_stream()` (it can be called multiple times to fill
|
||||
the buffer sized up to `ngtcp2_conn_get_send_quantum()` bytes), call
|
||||
the buffer sized up to `ngtcp2_conn_get_send_quantum2()` bytes), call
|
||||
`ngtcp2_conn_update_pkt_tx_time()` to set the timer when the next
|
||||
packet should be sent. The timer is integrated into
|
||||
`ngtcp2_conn_get_expiry()`.
|
||||
`ngtcp2_conn_get_expiry2()`.
|
||||
|
||||
Aggregate packets for GSO
|
||||
-------------------------
|
||||
|
|
@ -277,7 +402,7 @@ packets suitable for sending in GSO. It also enforces pacing
|
|||
automatically by calling `ngtcp2_conn_update_pkt_tx_time()`
|
||||
internally. Please note that `ngtcp2_conn_write_aggregate_pkt()`
|
||||
requires the buffer of at least
|
||||
`ngtcp2_conn_get_path_max_tx_udp_payload_size()` bytes long.
|
||||
`ngtcp2_conn_get_path_max_tx_udp_payload_size2()` bytes long.
|
||||
|
||||
Outgoing UDP datagram payload size
|
||||
----------------------------------
|
||||
|
|
@ -308,7 +433,7 @@ belongs to an existing connection, pass the UDP datagram to
|
|||
connection, it should be passed to `ngtcp2_accept()`. If it returns a
|
||||
negative error code, just drop the packet to the floor and take no
|
||||
action, or send Stateless Reset packet (use
|
||||
`ngtcp2_pkt_write_stateless_reset()` to create Stateless Reset
|
||||
`ngtcp2_pkt_write_stateless_reset2()` to create Stateless Reset
|
||||
packet). Otherwise, the UDP datagram is acceptable as a new
|
||||
connection. Create :type:`ngtcp2_conn` object and pass the UDP
|
||||
datagram to `ngtcp2_conn_read_pkt()`.
|
||||
|
|
@ -322,11 +447,12 @@ datagram is received, and it does not belong to any existing
|
|||
connections, and it is successfully processed by
|
||||
`ngtcp2_conn_read_pkt()`, associate the Destination Connection ID in
|
||||
the QUIC packet and :type:`ngtcp2_conn` object. The server must
|
||||
associate the Connection IDs returned by `ngtcp2_conn_get_scid()` to
|
||||
associate the Connection IDs returned by `ngtcp2_conn_get_scid2()` to
|
||||
the :type:`ngtcp2_conn` object as well. When new Connection ID is
|
||||
asked by the library, :member:`ngtcp2_callbacks.get_new_connection_id`
|
||||
is called. Inside the callback, associate the newly generated
|
||||
Connection ID to the :type:`ngtcp2_conn` object.
|
||||
asked by the library,
|
||||
:member:`ngtcp2_callbacks.get_new_connection_id2` is called. Inside
|
||||
the callback, associate the newly generated Connection ID to the
|
||||
:type:`ngtcp2_conn` object.
|
||||
|
||||
When Connection ID is no longer used, its association should be
|
||||
removed. When Connection ID is retired,
|
||||
|
|
@ -335,16 +461,16 @@ callback, remove the association for the Connection ID.
|
|||
|
||||
When a QUIC connection is closed, all associations for the connection
|
||||
should be removed. Remove all associations for Connection ID returned
|
||||
from `ngtcp2_conn_get_scid()`. Association for the initial Connection
|
||||
ID which can be obtained by calling
|
||||
`ngtcp2_conn_get_client_initial_dcid()` should also be removed.
|
||||
from `ngtcp2_conn_get_scid2()`. Association for the initial
|
||||
Connection ID which can be obtained by calling
|
||||
`ngtcp2_conn_get_client_initial_dcid2()` should also be removed.
|
||||
|
||||
Dealing with 0-RTT (early) data
|
||||
-------------------------------
|
||||
|
||||
Client application has to remember the subset of the QUIC transport
|
||||
parameters received from a server in the previous connection.
|
||||
`ngtcp2_conn_encode_0rtt_transport_params` returns the encoded QUIC
|
||||
`ngtcp2_conn_encode_0rtt_transport_params2` returns the encoded QUIC
|
||||
transport parameters that include these values. When sending 0-RTT
|
||||
data, the remembered transport parameters should be set via
|
||||
`ngtcp2_conn_decode_and_set_0rtt_transport_params`. Then client can
|
||||
|
|
@ -372,7 +498,7 @@ The send-side stream is closed when you call
|
|||
flag set, and all data are acknowledged. The receive-side stream is
|
||||
closed when a local endpoint receives fin from a remote endpoint, and
|
||||
all data are received. And then
|
||||
:member:`ngtcp2_callbacks.stream_close` is invoked.
|
||||
:member:`ngtcp2_callbacks.stream_close2` is invoked.
|
||||
|
||||
Application can close stream abruptly by calling
|
||||
`ngtcp2_conn_shutdown_stream`. It has
|
||||
|
|
@ -400,15 +526,21 @@ clock should work better. It should be same clock passed to
|
|||
:member:`ngtcp2_settings.initial_ts`. The duration in ngtcp2 library
|
||||
is :type:`ngtcp2_duration` which is also nanosecond resolution.
|
||||
|
||||
`ngtcp2_conn_get_expiry()` tells an application when timer fires.
|
||||
`ngtcp2_conn_get_expiry2()` tells an application when timer fires.
|
||||
When it fires, call `ngtcp2_conn_handle_expiry()`. If it returns
|
||||
:macro:`NGTCP2_ERR_IDLE_CLOSE`, it means that an idle timer has fired
|
||||
for this particular connection. In this case, drop the connection
|
||||
without calling `ngtcp2_conn_write_connection_close()`. Otherwise,
|
||||
call `ngtcp2_conn_writev_stream()`. After calling
|
||||
`ngtcp2_conn_handle_expiry()` and `ngtcp2_conn_writev_stream()`, new
|
||||
expiry is set. The application should call `ngtcp2_conn_get_expiry()`
|
||||
to get a new deadline.
|
||||
without calling `ngtcp2_conn_write_connection_close()`. If it returns
|
||||
any of the other negative error codes, close the connection by sending
|
||||
the terminal packet produced by
|
||||
`ngtcp2_conn_write_connection_close()`. Otherwise, schedule
|
||||
`ngtcp2_conn_writev_stream()` call. An application may call any
|
||||
number of additional `ngtcp2_conn_read_pkt()` and
|
||||
`ngtcp2_conn_handle_expiry()` before calling
|
||||
`ngtcp2_conn_writev_stream()`. After calling
|
||||
`ngtcp2_conn_writev_stream()`, new expiry is set. The application
|
||||
should call `ngtcp2_conn_get_expiry2()` to get a new deadline and set
|
||||
the timer.
|
||||
|
||||
Please note that :type:`ngtcp2_tstamp` of value ``UINT64_MAX`` is
|
||||
treated as an invalid timestamp. Do not pass ``UINT64_MAX`` to any
|
||||
|
|
|
|||
4
sources
4
sources
|
|
@ -1,2 +1,2 @@
|
|||
SHA512 (ngtcp2-1.21.0.tar.xz.asc) = 267ab883b912ae9cb294d441d2937446db1bb46e0ca7df1fe78a4108caf94f403af75ec01448a9ad01e9b5f6045db2929d22eeb8feebcf35c0ed1e83100eef63
|
||||
SHA512 (ngtcp2-1.21.0.tar.xz) = 8f1fab5f71364da2b42a3a2726089520b7b2bf751bd7ba3b8de153091cb36c6e983ab71cf2bb8cd62b29b665331dc08c5e40d106066f79474059a77e4f7f9361
|
||||
SHA512 (ngtcp2-1.25.0.tar.xz) = b5ebf0a4248a13b9231ac0b6353adbf6634a19bb57db3cf39947746c399ebc5085f780a540d246b7226bb994a920ad0cc9b755ebd9fe58c18a6838d50b6bc90e
|
||||
SHA512 (ngtcp2-1.25.0.tar.xz.asc) = cf0f325503ccfb65a770980cfd373fa88b9b89c0e56613f0dc058c3edc0a9a1c0324474fb4e58aca68b75831876b1000f7259f77a23db5e51fb07ec3e593e6f7
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue