mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
deps: update ngtcp2 to 1.14.0
Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: https://github.com/nodejs/node/pull/59249 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
0e754fa5d1
commit
dceb1fca40
39 changed files with 2582 additions and 731 deletions
6
deps/ngtcp2/README.md
vendored
6
deps/ngtcp2/README.md
vendored
|
@ -36,6 +36,9 @@ $ cp -R lib/* ../node/deps/ngtcp2/ngtcp2/lib/
|
|||
$ cp -R crypto/* ../node/deps/ngtcp2/ngtcp2/crypto/
|
||||
```
|
||||
|
||||
Be sure to also update the `ngtcp2.gyp` file to reflect any changes in
|
||||
the source files or include directories.
|
||||
|
||||
### Updating nghttp3
|
||||
|
||||
To update nghttp3, replace `v0.7.0` with the desired git tag:
|
||||
|
@ -47,3 +50,6 @@ $ autoreconf -i
|
|||
$ ./configure --prefix=$PWD/build --enable-lib-only
|
||||
$ cp -R lib/* ../node/deps/ngtcp2/nghttp3/lib/
|
||||
```
|
||||
|
||||
Be sure to also update the `ngtcp2.gyp` file to reflect any changes in
|
||||
the source files or include directories.
|
||||
|
|
9
deps/ngtcp2/ngtcp2.gyp
vendored
9
deps/ngtcp2/ngtcp2.gyp
vendored
|
@ -9,12 +9,13 @@
|
|||
'ngtcp2/lib/ngtcp2_balloc.c',
|
||||
'ngtcp2/lib/ngtcp2_bbr.c',
|
||||
'ngtcp2/lib/ngtcp2_buf.c',
|
||||
'ngtcp2/lib/ngtcp2_callbacks.c',
|
||||
'ngtcp2/lib/ngtcp2_cc.c',
|
||||
'ngtcp2/lib/ngtcp2_cid.c',
|
||||
'ngtcp2/lib/ngtcp2_conn.c',
|
||||
'ngtcp2/lib/ngtcp2_conv.c',
|
||||
'ngtcp2/lib/ngtcp2_dcidtr.c',
|
||||
'ngtcp2/lib/ngtcp2_crypto.c',
|
||||
'ngtcp2/lib/ngtcp2_dcidtr.c',
|
||||
'ngtcp2/lib/ngtcp2_err.c',
|
||||
'ngtcp2/lib/ngtcp2_frame_chain.c',
|
||||
'ngtcp2/lib/ngtcp2_gaptr.c',
|
||||
|
@ -47,8 +48,8 @@
|
|||
'ngtcp2/lib/ngtcp2_window_filter.c',
|
||||
'ngtcp2/crypto/shared.c'
|
||||
],
|
||||
'ngtcp2_sources_quictls': [
|
||||
#'ngtcp2/crypto/quictls/quictls.c'
|
||||
'ngtcp2_sources_ossl': [
|
||||
'ngtcp2/crypto/ossl/ossl.c'
|
||||
],
|
||||
'ngtcp2_sources_boringssl': [
|
||||
'ngtcp2/crypto/boringssl/boringssl.c'
|
||||
|
@ -142,7 +143,7 @@
|
|||
},
|
||||
'sources': [
|
||||
'<@(ngtcp2_sources)',
|
||||
'<@(ngtcp2_sources_quictls)',
|
||||
'<@(ngtcp2_sources_ossl)',
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -69,6 +69,13 @@ extern "C" {
|
|||
*/
|
||||
#define NGTCP2_CRYPTO_ERR_VERIFY_TOKEN -203
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_CRYPTO_ERR_NOMEM` indicates out of memory.
|
||||
*/
|
||||
#define NGTCP2_CRYPTO_ERR_NOMEM -501
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
|
|
198
deps/ngtcp2/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_ossl.h
vendored
Normal file
198
deps/ngtcp2/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto_ossl.h
vendored
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* ngtcp2
|
||||
*
|
||||
* Copyright (c) 2025 ngtcp2 contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGTCP2_CRYPTO_OSSL_H
|
||||
#define NGTCP2_CRYPTO_OSSL_H
|
||||
|
||||
#include <ngtcp2/ngtcp2.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
/**
|
||||
* @macrosection
|
||||
*
|
||||
* ossl specific error codes
|
||||
*/
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_CRYPTO_OSSL_ERR_TLS_WANT_X509_LOOKUP` is the error
|
||||
* code which indicates that TLS handshake routine is interrupted by
|
||||
* X509 certificate lookup. See :macro:`SSL_ERROR_WANT_X509_LOOKUP`
|
||||
* error description from `SSL_do_handshake`.
|
||||
*/
|
||||
#define NGTCP2_CRYPTO_OSSL_ERR_TLS_WANT_X509_LOOKUP -10001
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_CRYPTO_OSSL_ERR_TLS_WANT_CLIENT_HELLO_CB` is the
|
||||
* error code which indicates that TLS handshake routine is
|
||||
* interrupted by client hello callback. See
|
||||
* :macro:`SSL_ERROR_WANT_CLIENT_HELLO_CB` error description from
|
||||
* `SSL_do_handshake`.
|
||||
*/
|
||||
#define NGTCP2_CRYPTO_OSSL_ERR_TLS_WANT_CLIENT_HELLO_CB -10002
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_from_ossl_encryption_level` translates
|
||||
* |ossl_level| to :type:`ngtcp2_encryption_level`. This function is
|
||||
* only available for ossl backend.
|
||||
*/
|
||||
NGTCP2_EXTERN ngtcp2_encryption_level
|
||||
ngtcp2_crypto_ossl_from_ossl_encryption_level(uint32_t ossl_level);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_from_ngtcp2_encryption_level` translates
|
||||
* |encryption_level| to OpenSSL encryption level. This function is
|
||||
* only available for ossl backend.
|
||||
*/
|
||||
NGTCP2_EXTERN uint32_t ngtcp2_crypto_ossl_from_ngtcp2_encryption_level(
|
||||
ngtcp2_encryption_level encryption_level);
|
||||
|
||||
/**
|
||||
* @struct
|
||||
*
|
||||
* :type:`ngtcp2_crypto_ossl_ctx` contains per-connection state, and
|
||||
* must be set to `ngtcp2_conn_set_tls_native_handle`.
|
||||
*/
|
||||
typedef struct ngtcp2_crypto_ossl_ctx ngtcp2_crypto_ossl_ctx;
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_ctx_new` creates new
|
||||
* :type:`ngtcp2_crypto_ossl_ctx` object, and sets it to |*pctx| if it
|
||||
* succeeds.
|
||||
*
|
||||
* |ssl| is set to |*pctx|. It may be NULL, and in that case, call
|
||||
* `ngtcp2_crypto_ossl_ctx_set_ssl` later to set ``SSL`` object.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :enum:`NGTCP2_CRYPTO_ERR_NOMEM`
|
||||
* Out of memory
|
||||
*/
|
||||
NGTCP2_EXTERN int ngtcp2_crypto_ossl_ctx_new(ngtcp2_crypto_ossl_ctx **pctx,
|
||||
SSL *ssl);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_ctx_del` frees resources allocated for |ctx|.
|
||||
* It also frees memory pointed by |ctx|.
|
||||
*/
|
||||
NGTCP2_EXTERN void ngtcp2_crypto_ossl_ctx_del(ngtcp2_crypto_ossl_ctx *ctx);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_ctx_set_ssl` sets |ssl| to |ctx|. This
|
||||
* function must be called after ``SSL`` object is created.
|
||||
*/
|
||||
NGTCP2_EXTERN void ngtcp2_crypto_ossl_ctx_set_ssl(ngtcp2_crypto_ossl_ctx *ctx,
|
||||
SSL *ssl);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_ctx_get_ssl` returns ``SSL`` object set to
|
||||
* |ctx|. If the object has not been set, this function returns NULL.
|
||||
*/
|
||||
NGTCP2_EXTERN SSL *ngtcp2_crypto_ossl_ctx_get_ssl(ngtcp2_crypto_ossl_ctx *ctx);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_init` initializes libngtcp2_crypto_ossl
|
||||
* library. This initialization is optional. It is highly
|
||||
* recommended to call this function before any use of
|
||||
* libngtcp2_crypto library API to workaround the performance
|
||||
* regression.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
NGTCP2_EXTERN int ngtcp2_crypto_ossl_init(void);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_configure_server_session` configures |ssl| for
|
||||
* server side QUIC connection. It performs the following
|
||||
* modifications:
|
||||
*
|
||||
* - Register callbacks via ``SSL_set_quic_tls_cbs``
|
||||
*
|
||||
* Application must set a pointer to :type:`ngtcp2_crypto_conn_ref` to
|
||||
* SSL object by calling SSL_set_app_data, and
|
||||
* :type:`ngtcp2_crypto_conn_ref` object must have
|
||||
* :member:`ngtcp2_crypto_conn_ref.get_conn` field assigned to get
|
||||
* :type:`ngtcp2_conn`.
|
||||
*
|
||||
* Application must call ``SSL_set_app_data(ssl, NULL)`` before
|
||||
* calling ``SSL_free(ssl)`` if you cannot make `ngtcp2_conn` object
|
||||
* alive until ``SSL_free`` is called.
|
||||
*
|
||||
* It returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
NGTCP2_EXTERN int ngtcp2_crypto_ossl_configure_server_session(SSL *ssl);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `ngtcp2_crypto_ossl_configure_client_session` configures |ssl| for
|
||||
* client side QUIC connection. It performs the following
|
||||
* modifications:
|
||||
*
|
||||
* - Register callbacks via ``SSL_set_quic_tls_cbs``
|
||||
*
|
||||
* Application must set a pointer to :type:`ngtcp2_crypto_conn_ref` to
|
||||
* SSL object by calling SSL_set_app_data, and
|
||||
* :type:`ngtcp2_crypto_conn_ref` object must have
|
||||
* :member:`ngtcp2_crypto_conn_ref.get_conn` field assigned to get
|
||||
* :type:`ngtcp2_conn`.
|
||||
*
|
||||
* Application must call ``SSL_set_app_data(ssl, NULL)`` before
|
||||
* calling ``SSL_free(ssl)`` if you cannot make `ngtcp2_conn` object
|
||||
* alive until ``SSL_free`` is called.
|
||||
*
|
||||
* It returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
NGTCP2_EXTERN int ngtcp2_crypto_ossl_configure_client_session(SSL *ssl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif /* !defined(NGTCP2_CRYPTO_OSSL_H) */
|
|
@ -37,7 +37,7 @@ extern "C" {
|
|||
* @struct
|
||||
*
|
||||
* :type:`ngtcp2_crypto_picotls_ctx` contains per-connection state of
|
||||
* Picotls objects and must be an object to bet set to
|
||||
* Picotls object, and must be set to
|
||||
* `ngtcp2_conn_set_tls_native_handle`.
|
||||
*/
|
||||
typedef struct ngtcp2_crypto_picotls_ctx {
|
||||
|
|
1191
deps/ngtcp2/ngtcp2/crypto/ossl/ossl.c
vendored
Normal file
1191
deps/ngtcp2/ngtcp2/crypto/ossl/ossl.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
105
deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/ngtcp2.h
vendored
105
deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/ngtcp2.h
vendored
|
@ -214,18 +214,10 @@ typedef struct ngtcp2_mem {
|
|||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_SECONDS` is a count of tick which corresponds to 1
|
||||
* second.
|
||||
* :macro:`NGTCP2_NANOSECONDS` is a count of tick which corresponds to
|
||||
* 1 nanosecond.
|
||||
*/
|
||||
#define NGTCP2_SECONDS ((ngtcp2_duration)1000000000ULL)
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_MILLISECONDS` is a count of tick which corresponds
|
||||
* to 1 millisecond.
|
||||
*/
|
||||
#define NGTCP2_MILLISECONDS ((ngtcp2_duration)1000000ULL)
|
||||
#define NGTCP2_NANOSECONDS ((ngtcp2_duration)1ULL)
|
||||
|
||||
/**
|
||||
* @macro
|
||||
|
@ -233,15 +225,31 @@ typedef struct ngtcp2_mem {
|
|||
* :macro:`NGTCP2_MICROSECONDS` is a count of tick which corresponds
|
||||
* to 1 microsecond.
|
||||
*/
|
||||
#define NGTCP2_MICROSECONDS ((ngtcp2_duration)1000ULL)
|
||||
#define NGTCP2_MICROSECONDS ((ngtcp2_duration)(1000ULL * NGTCP2_NANOSECONDS))
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_NANOSECONDS` is a count of tick which corresponds to
|
||||
* 1 nanosecond.
|
||||
* :macro:`NGTCP2_MILLISECONDS` is a count of tick which corresponds
|
||||
* to 1 millisecond.
|
||||
*/
|
||||
#define NGTCP2_NANOSECONDS ((ngtcp2_duration)1ULL)
|
||||
#define NGTCP2_MILLISECONDS ((ngtcp2_duration)(1000ULL * NGTCP2_MICROSECONDS))
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_SECONDS` is a count of tick which corresponds to 1
|
||||
* second.
|
||||
*/
|
||||
#define NGTCP2_SECONDS ((ngtcp2_duration)(1000ULL * NGTCP2_MILLISECONDS))
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_MINUTES` is a count of tick which corresponds to 1
|
||||
* minute.
|
||||
*/
|
||||
#define NGTCP2_MINUTES ((ngtcp2_duration)(60ULL * NGTCP2_SECONDS))
|
||||
|
||||
/**
|
||||
* @macrosection
|
||||
|
@ -2858,7 +2866,8 @@ typedef int (*ngtcp2_extend_max_stream_data)(ngtcp2_conn *conn,
|
|||
* :type:`ngtcp2_rand` is a callback function to get random data of
|
||||
* length |destlen|. Application must fill random |destlen| bytes to
|
||||
* the buffer pointed by |dest|. The generated data is used only in
|
||||
* non-cryptographic context.
|
||||
* non-cryptographic context. But it is strongly recommended to use a
|
||||
* secure random number generator.
|
||||
*/
|
||||
typedef void (*ngtcp2_rand)(uint8_t *dest, size_t destlen,
|
||||
const ngtcp2_rand_ctx *rand_ctx);
|
||||
|
@ -2962,6 +2971,28 @@ typedef int (*ngtcp2_update_key)(
|
|||
*/
|
||||
#define NGTCP2_PATH_VALIDATION_FLAG_NEW_TOKEN 0x02u
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
* :type:`ngtcp2_begin_path_validation` is a callback function which
|
||||
* is called when the path validation has started. |flags| is zero or
|
||||
* more of :macro:`NGTCP2_PATH_VALIDATION_FLAG_*
|
||||
* <NGTCP2_PATH_VALIDATION_FLAG_NONE>`. |path| is the path that is
|
||||
* being validated. |fallback_path|, if not NULL, is the path that is
|
||||
* used when this validation fails.
|
||||
*
|
||||
* Currently, the flags may only contain
|
||||
* :macro:`NGTCP2_PATH_VALIDATION_FLAG_PREFERRED_ADDR`.
|
||||
*
|
||||
* The callback function must return 0 if it succeeds. Returning
|
||||
* :macro:`NGTCP2_ERR_CALLBACK_FAILURE` makes the library call return
|
||||
* immediately.
|
||||
*/
|
||||
typedef int (*ngtcp2_begin_path_validation)(ngtcp2_conn *conn, uint32_t flags,
|
||||
const ngtcp2_path *path,
|
||||
const ngtcp2_path *fallback_path,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
|
@ -3253,7 +3284,8 @@ typedef int (*ngtcp2_tls_early_data_rejected)(ngtcp2_conn *conn,
|
|||
void *user_data);
|
||||
|
||||
#define NGTCP2_CALLBACKS_V1 1
|
||||
#define NGTCP2_CALLBACKS_VERSION NGTCP2_CALLBACKS_V1
|
||||
#define NGTCP2_CALLBACKS_V2 2
|
||||
#define NGTCP2_CALLBACKS_VERSION NGTCP2_CALLBACKS_V2
|
||||
|
||||
/**
|
||||
* @struct
|
||||
|
@ -3518,6 +3550,13 @@ typedef struct ngtcp2_callbacks {
|
|||
* is only used by client.
|
||||
*/
|
||||
ngtcp2_tls_early_data_rejected tls_early_data_rejected;
|
||||
/* The following fields have been added since NGTCP2_CALLBACKS_V2. */
|
||||
/**
|
||||
* :member:`begin_path_validation` is a callback function which is
|
||||
* invoked when a path validation has started. This field is
|
||||
* available since v1.14.0.
|
||||
*/
|
||||
ngtcp2_begin_path_validation begin_path_validation;
|
||||
} ngtcp2_callbacks;
|
||||
|
||||
/**
|
||||
|
@ -4398,6 +4437,17 @@ NGTCP2_EXTERN int ngtcp2_conn_shutdown_stream_read(ngtcp2_conn *conn,
|
|||
*/
|
||||
#define NGTCP2_WRITE_STREAM_FLAG_FIN 0x02u
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_WRITE_STREAM_FLAG_PADDING` indicates that a
|
||||
* non-empty 0 RTT or 1 RTT ack-eliciting packet is padded to the
|
||||
* minimum length of a sending path MTU or a given packet buffer when
|
||||
* finalizing it. PATH_CHALLENGE, PATH_RESPONSE, CONNECTION_CLOSE
|
||||
* only packets and PMTUD packets are excluded.
|
||||
*/
|
||||
#define NGTCP2_WRITE_STREAM_FLAG_PADDING 0x04u
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
|
@ -4522,6 +4572,11 @@ NGTCP2_EXTERN ngtcp2_ssize ngtcp2_conn_write_stream_versioned(
|
|||
* include, call this function with |stream_id| as -1 to stop
|
||||
* coalescing and write a packet.
|
||||
*
|
||||
* If :macro:`NGTCP2_WRITE_STREAM_FLAG_PADDING` is set in |flags| when
|
||||
* finalizing a non-empty 0 RTT or 1 RTT ack-eliciting packet, the
|
||||
* packet is padded to the minimum length of a sending path MTU or a
|
||||
* given packet buffer.
|
||||
*
|
||||
* This function returns 0 if it cannot write any frame because buffer
|
||||
* is too small, or packet is congestion limited. Application should
|
||||
* keep reading and wait for congestion window to grow.
|
||||
|
@ -4586,6 +4641,17 @@ NGTCP2_EXTERN ngtcp2_ssize ngtcp2_conn_writev_stream_versioned(
|
|||
*/
|
||||
#define NGTCP2_WRITE_DATAGRAM_FLAG_MORE 0x01u
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`NGTCP2_WRITE_DATAGRAM_FLAG_PADDING` indicates that a
|
||||
* non-empty 0 RTT or 1 RTT ack-eliciting packet is padded to the
|
||||
* minimum length of a sending path MTU or a given packet buffer when
|
||||
* finalizing it. PATH_CHALLENGE, PATH_RESPONSE, CONNECTION_CLOSE
|
||||
* only packets and PMTUD packets are excluded.
|
||||
*/
|
||||
#define NGTCP2_WRITE_DATAGRAM_FLAG_PADDING 0x02u
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
|
@ -4667,6 +4733,11 @@ NGTCP2_EXTERN ngtcp2_ssize ngtcp2_conn_write_datagram_versioned(
|
|||
* (or `ngtcp2_conn_writev_stream`) until it returns a positive number
|
||||
* (which indicates a complete packet is ready).
|
||||
*
|
||||
* If :macro:`NGTCP2_WRITE_DATAGRAM_FLAG_PADDING` is set in |flags|
|
||||
* when finalizing a non-empty 0 RTT or 1 RTT ack-eliciting packet,
|
||||
* the packet is padded to the minimum length of a sending path MTU or
|
||||
* a given packet buffer.
|
||||
*
|
||||
* This function returns the number of bytes written in |dest| if it
|
||||
* succeeds, or one of the following negative error codes:
|
||||
*
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
*
|
||||
* Version number of the ngtcp2 library release.
|
||||
*/
|
||||
#define NGTCP2_VERSION "1.11.0"
|
||||
#define NGTCP2_VERSION "1.14.0"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
|
@ -46,6 +46,6 @@
|
|||
* number, 8 bits for minor and 8 bits for patch. Version 1.2.3
|
||||
* becomes 0x010203.
|
||||
*/
|
||||
#define NGTCP2_VERSION_NUM 0x010b00
|
||||
#define NGTCP2_VERSION_NUM 0x010e00
|
||||
|
||||
#endif /* !defined(NGTCP2_VERSION_H) */
|
||||
|
|
252
deps/ngtcp2/ngtcp2/lib/ngtcp2_bbr.c
vendored
252
deps/ngtcp2/ngtcp2/lib/ngtcp2_bbr.c
vendored
|
@ -69,7 +69,7 @@ static void bbr_on_transmit(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
|||
|
||||
static void bbr_reset_congestion_signals(ngtcp2_cc_bbr *bbr);
|
||||
|
||||
static void bbr_reset_lower_bounds(ngtcp2_cc_bbr *bbr);
|
||||
static void bbr_reset_shortterm_model(ngtcp2_cc_bbr *bbr);
|
||||
|
||||
static void bbr_init_round_counting(ngtcp2_cc_bbr *bbr);
|
||||
|
||||
|
@ -157,8 +157,7 @@ static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
|
|||
const ngtcp2_cc_ack *ack,
|
||||
ngtcp2_tstamp ts);
|
||||
|
||||
static int bbr_is_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||
ngtcp2_tstamp ts);
|
||||
static int bbr_is_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
|
||||
|
||||
static int bbr_is_time_to_go_down(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
|
||||
|
||||
|
@ -168,15 +167,16 @@ static int bbr_has_elapsed_in_phase(ngtcp2_cc_bbr *bbr,
|
|||
static uint64_t bbr_inflight_with_headroom(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat);
|
||||
|
||||
static void bbr_raise_inflight_hi_slope(ngtcp2_cc_bbr *bbr,
|
||||
static void bbr_raise_inflight_longterm_slope(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat);
|
||||
|
||||
static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
|
||||
static void bbr_probe_inflight_longterm_upward(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_ack *ack);
|
||||
|
||||
static void bbr_adapt_upper_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
|
||||
static void bbr_adapt_longterm_model(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_ack *ack);
|
||||
|
||||
static int bbr_is_time_to_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||
ngtcp2_tstamp ts);
|
||||
|
@ -189,23 +189,19 @@ static int bbr_is_reno_coexistence_probe_time(ngtcp2_cc_bbr *bbr,
|
|||
static uint64_t bbr_target_inflight(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat);
|
||||
|
||||
static int bbr_check_inflight_too_high(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
ngtcp2_tstamp ts);
|
||||
|
||||
static int is_inflight_too_high(const ngtcp2_rs *rs);
|
||||
static int bbr_is_inflight_too_high(ngtcp2_cc_bbr *bbr);
|
||||
|
||||
static void bbr_handle_inflight_too_high(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_rs *rs, ngtcp2_tstamp ts);
|
||||
ngtcp2_tstamp ts);
|
||||
|
||||
static void bbr_note_loss(ngtcp2_cc_bbr *bbr);
|
||||
|
||||
static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts);
|
||||
|
||||
static uint64_t bbr_inflight_hi_from_lost_packet(ngtcp2_cc_bbr *bbr,
|
||||
const ngtcp2_rs *rs,
|
||||
static uint64_t
|
||||
bbr_inflight_longterm_from_lost_packet(ngtcp2_cc_bbr *bbr,
|
||||
const ngtcp2_cc_pkt *pkt);
|
||||
|
||||
static void bbr_update_min_rtt(ngtcp2_cc_bbr *bbr, const ngtcp2_cc_ack *ack,
|
||||
|
@ -292,7 +288,7 @@ static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
|||
bbr->full_bw_reached = 0;
|
||||
|
||||
bbr_reset_congestion_signals(bbr);
|
||||
bbr_reset_lower_bounds(bbr);
|
||||
bbr_reset_shortterm_model(bbr);
|
||||
bbr_init_round_counting(bbr);
|
||||
bbr_reset_full_bw(bbr);
|
||||
bbr_init_pacing_rate(bbr, cstat);
|
||||
|
@ -326,7 +322,7 @@ static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
|||
bbr->bw_probe_up_rounds = 0;
|
||||
bbr->bw_probe_up_acks = 0;
|
||||
|
||||
bbr->inflight_hi = UINT64_MAX;
|
||||
bbr->inflight_longterm = UINT64_MAX;
|
||||
|
||||
bbr->probe_rtt_expired = 0;
|
||||
bbr->probe_rtt_min_delay = UINT64_MAX;
|
||||
|
@ -348,9 +344,9 @@ static void bbr_reset_congestion_signals(ngtcp2_cc_bbr *bbr) {
|
|||
bbr->inflight_latest = 0;
|
||||
}
|
||||
|
||||
static void bbr_reset_lower_bounds(ngtcp2_cc_bbr *bbr) {
|
||||
bbr->bw_lo = UINT64_MAX;
|
||||
bbr->inflight_lo = UINT64_MAX;
|
||||
static void bbr_reset_shortterm_model(ngtcp2_cc_bbr *bbr) {
|
||||
bbr->bw_shortterm = UINT64_MAX;
|
||||
bbr->inflight_shortterm = UINT64_MAX;
|
||||
}
|
||||
|
||||
static void bbr_init_round_counting(ngtcp2_cc_bbr *bbr) {
|
||||
|
@ -367,7 +363,7 @@ static void bbr_reset_full_bw(ngtcp2_cc_bbr *bbr) {
|
|||
|
||||
static void bbr_check_full_bw_reached(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat) {
|
||||
if (bbr->full_bw_now || bbr->rst->rs.is_app_limited) {
|
||||
if (bbr->full_bw_now || !bbr->round_start || bbr->rst->rs.is_app_limited) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -378,10 +374,6 @@ static void bbr_check_full_bw_reached(ngtcp2_cc_bbr *bbr,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!bbr->round_start) {
|
||||
return;
|
||||
}
|
||||
|
||||
++bbr->full_bw_count;
|
||||
|
||||
bbr->full_bw_now = bbr->full_bw_count >= 3;
|
||||
|
@ -399,36 +391,38 @@ static void bbr_check_startup_high_loss(ngtcp2_cc_bbr *bbr) {
|
|||
if (bbr->full_bw_reached || bbr->loss_events_in_round <= 6 ||
|
||||
(bbr->in_loss_recovery &&
|
||||
bbr->round_count <= bbr->round_count_at_recovery) ||
|
||||
!is_inflight_too_high(&bbr->rst->rs)) {
|
||||
!bbr_is_inflight_too_high(bbr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bbr->full_bw_reached = 1;
|
||||
bbr->inflight_hi = ngtcp2_max_uint64(bbr_bdp_multiple(bbr, bbr->cwnd_gain_h),
|
||||
bbr->inflight_latest);
|
||||
bbr->inflight_longterm = ngtcp2_max_uint64(
|
||||
bbr_bdp_multiple(bbr, bbr->cwnd_gain_h), bbr->inflight_latest);
|
||||
}
|
||||
|
||||
static void bbr_init_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
|
||||
cstat->pacing_interval =
|
||||
(cstat->first_rtt_sample_ts == UINT64_MAX ? NGTCP2_MILLISECONDS
|
||||
: cstat->smoothed_rtt) *
|
||||
cstat->pacing_interval_m =
|
||||
((cstat->first_rtt_sample_ts == UINT64_MAX ? NGTCP2_MILLISECONDS
|
||||
: cstat->smoothed_rtt)
|
||||
<< 10) *
|
||||
100 / NGTCP2_BBR_STARTUP_PACING_GAIN_H / bbr->initial_cwnd;
|
||||
}
|
||||
|
||||
static void bbr_set_pacing_rate_with_gain(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
uint64_t pacing_gain_h) {
|
||||
ngtcp2_duration interval;
|
||||
uint64_t interval_m;
|
||||
|
||||
if (bbr->bw == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
interval = NGTCP2_SECONDS * 100 * 100 / pacing_gain_h / bbr->bw /
|
||||
interval_m = (NGTCP2_SECONDS << 10) * 100 * 100 / pacing_gain_h / bbr->bw /
|
||||
(100 - NGTCP2_BBR_PACING_MARGIN_PERCENT);
|
||||
interval_m = ngtcp2_max_uint64(interval_m, 1);
|
||||
|
||||
if (bbr->full_bw_reached || interval < cstat->pacing_interval) {
|
||||
cstat->pacing_interval = interval;
|
||||
if (bbr->full_bw_reached || interval_m < cstat->pacing_interval_m) {
|
||||
cstat->pacing_interval_m = interval_m;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,25 +540,26 @@ static void bbr_adapt_lower_bounds_from_congestion(ngtcp2_cc_bbr *bbr,
|
|||
}
|
||||
|
||||
static void bbr_init_lower_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
|
||||
if (bbr->bw_lo == UINT64_MAX) {
|
||||
bbr->bw_lo = bbr->max_bw;
|
||||
if (bbr->bw_shortterm == UINT64_MAX) {
|
||||
bbr->bw_shortterm = bbr->max_bw;
|
||||
}
|
||||
|
||||
if (bbr->inflight_lo == UINT64_MAX) {
|
||||
bbr->inflight_lo = cstat->cwnd;
|
||||
if (bbr->inflight_shortterm == UINT64_MAX) {
|
||||
bbr->inflight_shortterm = cstat->cwnd;
|
||||
}
|
||||
}
|
||||
|
||||
static void bbr_loss_lower_bounds(ngtcp2_cc_bbr *bbr) {
|
||||
bbr->bw_lo = ngtcp2_max_uint64(
|
||||
bbr->bw_latest, bbr->bw_lo * NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
|
||||
bbr->inflight_lo = ngtcp2_max_uint64(
|
||||
bbr->bw_shortterm = ngtcp2_max_uint64(
|
||||
bbr->bw_latest,
|
||||
bbr->bw_shortterm * NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
|
||||
bbr->inflight_shortterm = ngtcp2_max_uint64(
|
||||
bbr->inflight_latest,
|
||||
bbr->inflight_lo * NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
|
||||
bbr->inflight_shortterm * NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
|
||||
}
|
||||
|
||||
static void bbr_bound_bw_for_model(ngtcp2_cc_bbr *bbr) {
|
||||
bbr->bw = ngtcp2_min_uint64(bbr->max_bw, bbr->bw_lo);
|
||||
bbr->bw = ngtcp2_min_uint64(bbr->max_bw, bbr->bw_shortterm);
|
||||
}
|
||||
|
||||
static void bbr_update_max_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||
|
@ -712,7 +707,7 @@ static void bbr_start_probe_bw_refill(ngtcp2_cc_bbr *bbr) {
|
|||
ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA,
|
||||
"bbr start ProbeBW_REFILL");
|
||||
|
||||
bbr_reset_lower_bounds(bbr);
|
||||
bbr_reset_shortterm_model(bbr);
|
||||
|
||||
bbr->bw_probe_up_rounds = 0;
|
||||
bbr->bw_probe_up_acks = 0;
|
||||
|
@ -738,7 +733,7 @@ static void bbr_start_probe_bw_up(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
|
|||
bbr->pacing_gain_h = 125;
|
||||
bbr->cwnd_gain_h = 225;
|
||||
|
||||
bbr_raise_inflight_hi_slope(bbr, cstat);
|
||||
bbr_raise_inflight_longterm_slope(bbr, cstat);
|
||||
}
|
||||
|
||||
static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
|
||||
|
@ -749,7 +744,7 @@ static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
|
|||
return;
|
||||
}
|
||||
|
||||
bbr_adapt_upper_bounds(bbr, cstat, ack, ts);
|
||||
bbr_adapt_longterm_model(bbr, cstat, ack);
|
||||
|
||||
if (!bbr_is_in_probe_bw_state(bbr)) {
|
||||
return;
|
||||
|
@ -761,7 +756,7 @@ static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
|
|||
return;
|
||||
}
|
||||
|
||||
if (bbr_is_time_to_cruise(bbr, cstat, ts)) {
|
||||
if (bbr_is_time_to_cruise(bbr, cstat)) {
|
||||
bbr_start_probe_bw_cruise(bbr);
|
||||
}
|
||||
|
||||
|
@ -790,30 +785,22 @@ static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
|
|||
}
|
||||
}
|
||||
|
||||
static int bbr_is_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||
ngtcp2_tstamp ts) {
|
||||
(void)ts;
|
||||
static int bbr_is_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
|
||||
uint64_t inflight = ngtcp2_min_uint64(bbr_inflight_with_headroom(bbr, cstat),
|
||||
bbr_inflight(bbr, cstat, 100));
|
||||
|
||||
if (cstat->bytes_in_flight > bbr_inflight_with_headroom(bbr, cstat)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, 100)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cstat->bytes_in_flight <= inflight;
|
||||
}
|
||||
|
||||
static int bbr_is_time_to_go_down(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
|
||||
if (bbr->rst->is_cwnd_limited && cstat->cwnd >= bbr->inflight_hi) {
|
||||
if (bbr->rst->is_cwnd_limited && cstat->cwnd >= bbr->inflight_longterm) {
|
||||
bbr_reset_full_bw(bbr);
|
||||
bbr->full_bw = cstat->delivery_rate_sec;
|
||||
} else if (bbr->full_bw_now) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bbr->full_bw_now;
|
||||
}
|
||||
|
||||
static int bbr_has_elapsed_in_phase(ngtcp2_cc_bbr *bbr,
|
||||
|
@ -826,23 +813,24 @@ static uint64_t bbr_inflight_with_headroom(ngtcp2_cc_bbr *bbr,
|
|||
ngtcp2_conn_stat *cstat) {
|
||||
uint64_t headroom;
|
||||
uint64_t mpcwnd;
|
||||
if (bbr->inflight_hi == UINT64_MAX) {
|
||||
if (bbr->inflight_longterm == UINT64_MAX) {
|
||||
return UINT64_MAX;
|
||||
}
|
||||
|
||||
headroom = ngtcp2_max_uint64(cstat->max_tx_udp_payload_size,
|
||||
bbr->inflight_hi * NGTCP2_BBR_HEADROOM_NUMER /
|
||||
headroom =
|
||||
ngtcp2_max_uint64(cstat->max_tx_udp_payload_size,
|
||||
bbr->inflight_longterm * NGTCP2_BBR_HEADROOM_NUMER /
|
||||
NGTCP2_BBR_HEADROOM_DENOM);
|
||||
mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
|
||||
|
||||
if (bbr->inflight_hi > headroom) {
|
||||
return ngtcp2_max_uint64(bbr->inflight_hi - headroom, mpcwnd);
|
||||
if (bbr->inflight_longterm > headroom) {
|
||||
return ngtcp2_max_uint64(bbr->inflight_longterm - headroom, mpcwnd);
|
||||
}
|
||||
|
||||
return mpcwnd;
|
||||
}
|
||||
|
||||
static void bbr_raise_inflight_hi_slope(ngtcp2_cc_bbr *bbr,
|
||||
static void bbr_raise_inflight_longterm_slope(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat) {
|
||||
uint64_t growth_this_round = cstat->max_tx_udp_payload_size
|
||||
<< bbr->bw_probe_up_rounds;
|
||||
|
@ -851,12 +839,12 @@ static void bbr_raise_inflight_hi_slope(ngtcp2_cc_bbr *bbr,
|
|||
bbr->probe_up_cnt = ngtcp2_max_uint64(cstat->cwnd / growth_this_round, 1);
|
||||
}
|
||||
|
||||
static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
|
||||
static void bbr_probe_inflight_longterm_upward(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_ack *ack) {
|
||||
uint64_t delta;
|
||||
|
||||
if (!bbr->rst->is_cwnd_limited || cstat->cwnd < bbr->inflight_hi) {
|
||||
if (!bbr->rst->is_cwnd_limited || cstat->cwnd < bbr->inflight_longterm) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -867,16 +855,17 @@ static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
|
|||
bbr->probe_up_cnt * cstat->max_tx_udp_payload_size) {
|
||||
delta = bbr->bw_probe_up_acks / bbr->probe_up_cnt;
|
||||
bbr->bw_probe_up_acks -= delta * bbr->probe_up_cnt;
|
||||
bbr->inflight_hi += delta;
|
||||
bbr->inflight_longterm += delta;
|
||||
}
|
||||
|
||||
if (bbr->round_start) {
|
||||
bbr_raise_inflight_hi_slope(bbr, cstat);
|
||||
bbr_raise_inflight_longterm_slope(bbr, cstat);
|
||||
}
|
||||
}
|
||||
|
||||
static void bbr_adapt_upper_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
|
||||
static void bbr_adapt_longterm_model(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_ack *ack) {
|
||||
if (bbr->ack_phase == NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_STARTING &&
|
||||
bbr->round_start) {
|
||||
bbr->ack_phase = NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_FEEDBACK;
|
||||
|
@ -889,17 +878,17 @@ static void bbr_adapt_upper_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
|||
}
|
||||
}
|
||||
|
||||
if (!bbr_check_inflight_too_high(bbr, cstat, ts)) {
|
||||
if (bbr->inflight_hi == UINT64_MAX) {
|
||||
if (!bbr_is_inflight_too_high(bbr)) {
|
||||
if (bbr->inflight_longterm == UINT64_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bbr->rst->rs.tx_in_flight > bbr->inflight_hi) {
|
||||
bbr->inflight_hi = bbr->rst->rs.tx_in_flight;
|
||||
if (bbr->rst->rs.tx_in_flight > bbr->inflight_longterm) {
|
||||
bbr->inflight_longterm = bbr->rst->rs.tx_in_flight;
|
||||
}
|
||||
|
||||
if (bbr->state == NGTCP2_BBR_STATE_PROBE_BW_UP) {
|
||||
bbr_probe_inflight_hi_upward(bbr, cstat, ack);
|
||||
bbr_probe_inflight_longterm_upward(bbr, cstat, ack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -921,7 +910,7 @@ static void bbr_pick_probe_wait(ngtcp2_cc_bbr *bbr) {
|
|||
|
||||
bbr->rand(&rand, 1, &bbr->rand_ctx);
|
||||
|
||||
bbr->rounds_since_bw_probe = (uint64_t)(rand * 2 / 256);
|
||||
bbr->rounds_since_bw_probe = (uint64_t)(rand / 128);
|
||||
|
||||
bbr->rand(&rand, 1, &bbr->rand_ctx);
|
||||
|
||||
|
@ -941,33 +930,21 @@ static uint64_t bbr_target_inflight(ngtcp2_cc_bbr *bbr,
|
|||
return ngtcp2_min_uint64(bbr->bdp, cstat->cwnd);
|
||||
}
|
||||
|
||||
static int bbr_check_inflight_too_high(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
ngtcp2_tstamp ts) {
|
||||
if (is_inflight_too_high(&bbr->rst->rs)) {
|
||||
if (bbr->bw_probe_samples) {
|
||||
bbr_handle_inflight_too_high(bbr, cstat, &bbr->rst->rs, ts);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_inflight_too_high(const ngtcp2_rs *rs) {
|
||||
static int bbr_is_inflight_too_high(ngtcp2_cc_bbr *bbr) {
|
||||
const ngtcp2_rs *rs = &bbr->rst->rs;
|
||||
return rs->lost * NGTCP2_BBR_LOSS_THRESH_DENOM >
|
||||
rs->tx_in_flight * NGTCP2_BBR_LOSS_THRESH_NUMER;
|
||||
}
|
||||
|
||||
static void bbr_handle_inflight_too_high(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_rs *rs,
|
||||
ngtcp2_tstamp ts) {
|
||||
const ngtcp2_rs *rs = &bbr->rst->rs;
|
||||
|
||||
bbr->bw_probe_samples = 0;
|
||||
|
||||
if (!rs->is_app_limited) {
|
||||
bbr->inflight_hi = ngtcp2_max_uint64(
|
||||
bbr->inflight_longterm = ngtcp2_max_uint64(
|
||||
rs->tx_in_flight, bbr_target_inflight(bbr, cstat) *
|
||||
NGTCP2_BBR_BETA_NUMER / NGTCP2_BBR_BETA_DENOM);
|
||||
}
|
||||
|
@ -987,7 +964,7 @@ static void bbr_note_loss(ngtcp2_cc_bbr *bbr) {
|
|||
|
||||
static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
|
||||
ngtcp2_rs rs = {0};
|
||||
ngtcp2_rs *rs = &bbr->rst->rs;
|
||||
|
||||
bbr_note_loss(bbr);
|
||||
|
||||
|
@ -995,22 +972,22 @@ static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
|||
return;
|
||||
}
|
||||
|
||||
rs.tx_in_flight = pkt->tx_in_flight;
|
||||
/* bbr->rst->lost is not incremented for pkt yet */
|
||||
assert(bbr->rst->lost + pkt->pktlen >= pkt->lost);
|
||||
rs.lost = bbr->rst->lost + pkt->pktlen - pkt->lost;
|
||||
rs.is_app_limited = pkt->is_app_limited;
|
||||
rs->tx_in_flight = pkt->tx_in_flight;
|
||||
assert(bbr->rst->lost >= pkt->lost);
|
||||
rs->lost = bbr->rst->lost - pkt->lost;
|
||||
rs->is_app_limited = pkt->is_app_limited;
|
||||
|
||||
if (is_inflight_too_high(&rs)) {
|
||||
rs.tx_in_flight = bbr_inflight_hi_from_lost_packet(bbr, &rs, pkt);
|
||||
if (bbr_is_inflight_too_high(bbr)) {
|
||||
rs->tx_in_flight = bbr_inflight_longterm_from_lost_packet(bbr, pkt);
|
||||
|
||||
bbr_handle_inflight_too_high(bbr, cstat, &rs, ts);
|
||||
bbr_handle_inflight_too_high(bbr, cstat, ts);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t bbr_inflight_hi_from_lost_packet(ngtcp2_cc_bbr *bbr,
|
||||
const ngtcp2_rs *rs,
|
||||
static uint64_t
|
||||
bbr_inflight_longterm_from_lost_packet(ngtcp2_cc_bbr *bbr,
|
||||
const ngtcp2_cc_pkt *pkt) {
|
||||
ngtcp2_rs *rs = &bbr->rst->rs;
|
||||
uint64_t inflight_prev, lost_prev, lost_prefix;
|
||||
(void)bbr;
|
||||
|
||||
|
@ -1136,7 +1113,7 @@ static void bbr_mark_connection_app_limited(ngtcp2_cc_bbr *bbr,
|
|||
}
|
||||
|
||||
static void bbr_exit_probe_rtt(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts) {
|
||||
bbr_reset_lower_bounds(bbr);
|
||||
bbr_reset_shortterm_model(bbr);
|
||||
|
||||
if (bbr->full_bw_reached) {
|
||||
bbr_start_probe_bw_down(bbr, ts);
|
||||
|
@ -1204,9 +1181,6 @@ static void bbr_update_max_inflight(ngtcp2_cc_bbr *bbr,
|
|||
ngtcp2_conn_stat *cstat) {
|
||||
uint64_t inflight;
|
||||
|
||||
/* Not documented */
|
||||
/* bbr_update_aggregation_budget(bbr); */
|
||||
|
||||
inflight = bbr_bdp_multiple(bbr, bbr->cwnd_gain_h) + bbr->extra_acked;
|
||||
bbr->max_inflight = bbr_quantization_budget(bbr, cstat, inflight);
|
||||
}
|
||||
|
@ -1244,12 +1218,9 @@ static uint64_t bbr_probe_rtt_cwnd(ngtcp2_cc_bbr *bbr,
|
|||
|
||||
static void bbr_bound_cwnd_for_probe_rtt(ngtcp2_cc_bbr *bbr,
|
||||
ngtcp2_conn_stat *cstat) {
|
||||
uint64_t probe_rtt_cwnd;
|
||||
|
||||
if (bbr->state == NGTCP2_BBR_STATE_PROBE_RTT) {
|
||||
probe_rtt_cwnd = bbr_probe_rtt_cwnd(bbr, cstat);
|
||||
|
||||
cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, probe_rtt_cwnd);
|
||||
cstat->cwnd =
|
||||
ngtcp2_min_uint64(cstat->cwnd, bbr_probe_rtt_cwnd(bbr, cstat));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1281,13 +1252,13 @@ static void bbr_bound_cwnd_for_model(ngtcp2_cc_bbr *bbr,
|
|||
|
||||
if (bbr_is_in_probe_bw_state(bbr) &&
|
||||
bbr->state != NGTCP2_BBR_STATE_PROBE_BW_CRUISE) {
|
||||
cap = bbr->inflight_hi;
|
||||
cap = bbr->inflight_longterm;
|
||||
} else if (bbr->state == NGTCP2_BBR_STATE_PROBE_RTT ||
|
||||
bbr->state == NGTCP2_BBR_STATE_PROBE_BW_CRUISE) {
|
||||
cap = bbr_inflight_with_headroom(bbr, cstat);
|
||||
}
|
||||
|
||||
cap = ngtcp2_min_uint64(cap, bbr->inflight_lo);
|
||||
cap = ngtcp2_min_uint64(cap, bbr->inflight_shortterm);
|
||||
cap = ngtcp2_max_uint64(cap, mpcwnd);
|
||||
|
||||
cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, cap);
|
||||
|
@ -1297,10 +1268,9 @@ static void bbr_set_send_quantum(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
|
|||
size_t send_quantum = 64 * 1024;
|
||||
(void)bbr;
|
||||
|
||||
if (cstat->pacing_interval) {
|
||||
send_quantum = ngtcp2_min_size(
|
||||
send_quantum, (size_t)(NGTCP2_MILLISECONDS / cstat->pacing_interval));
|
||||
}
|
||||
send_quantum =
|
||||
ngtcp2_min_size(send_quantum, (size_t)((NGTCP2_MILLISECONDS << 10) /
|
||||
cstat->pacing_interval_m));
|
||||
|
||||
cstat->send_quantum =
|
||||
ngtcp2_max_size(send_quantum, 2 * cstat->max_tx_udp_payload_size);
|
||||
|
@ -1420,21 +1390,23 @@ void ngtcp2_cc_bbr_init(ngtcp2_cc_bbr *bbr, ngtcp2_log *log,
|
|||
ngtcp2_conn_stat *cstat, ngtcp2_rst *rst,
|
||||
ngtcp2_tstamp initial_ts, ngtcp2_rand rand,
|
||||
const ngtcp2_rand_ctx *rand_ctx) {
|
||||
memset(bbr, 0, sizeof(*bbr));
|
||||
|
||||
bbr->cc.log = log;
|
||||
bbr->cc.on_pkt_lost = bbr_cc_on_pkt_lost;
|
||||
bbr->cc.congestion_event = bbr_cc_congestion_event;
|
||||
bbr->cc.on_spurious_congestion = bbr_cc_on_spurious_congestion;
|
||||
bbr->cc.on_persistent_congestion = bbr_cc_on_persistent_congestion;
|
||||
bbr->cc.on_ack_recv = bbr_cc_on_ack_recv;
|
||||
bbr->cc.on_pkt_sent = bbr_cc_on_pkt_sent;
|
||||
bbr->cc.reset = bbr_cc_reset;
|
||||
|
||||
bbr->rst = rst;
|
||||
bbr->rand = rand;
|
||||
bbr->rand_ctx = *rand_ctx;
|
||||
bbr->initial_cwnd = cstat->cwnd;
|
||||
*bbr = (ngtcp2_cc_bbr){
|
||||
.cc =
|
||||
{
|
||||
.log = log,
|
||||
.on_pkt_lost = bbr_cc_on_pkt_lost,
|
||||
.congestion_event = bbr_cc_congestion_event,
|
||||
.on_spurious_congestion = bbr_cc_on_spurious_congestion,
|
||||
.on_persistent_congestion = bbr_cc_on_persistent_congestion,
|
||||
.on_ack_recv = bbr_cc_on_ack_recv,
|
||||
.on_pkt_sent = bbr_cc_on_pkt_sent,
|
||||
.reset = bbr_cc_reset,
|
||||
},
|
||||
.rst = rst,
|
||||
.rand = rand,
|
||||
.rand_ctx = *rand_ctx,
|
||||
.initial_cwnd = cstat->cwnd,
|
||||
};
|
||||
|
||||
bbr_on_init(bbr, cstat, initial_ts);
|
||||
}
|
||||
|
|
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_bbr.h
vendored
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_bbr.h
vendored
|
@ -86,8 +86,8 @@ typedef struct ngtcp2_cc_bbr {
|
|||
uint64_t inflight_latest;
|
||||
|
||||
/* Lower bounds */
|
||||
uint64_t bw_lo;
|
||||
uint64_t inflight_lo;
|
||||
uint64_t bw_shortterm;
|
||||
uint64_t inflight_shortterm;
|
||||
|
||||
/* Round counting */
|
||||
uint64_t next_round_delivered;
|
||||
|
@ -123,7 +123,7 @@ typedef struct ngtcp2_cc_bbr {
|
|||
int bw_probe_samples;
|
||||
size_t bw_probe_up_rounds;
|
||||
uint64_t bw_probe_up_acks;
|
||||
uint64_t inflight_hi;
|
||||
uint64_t inflight_longterm;
|
||||
int probe_rtt_expired;
|
||||
ngtcp2_duration probe_rtt_min_delay;
|
||||
ngtcp2_tstamp probe_rtt_min_stamp;
|
||||
|
|
8
deps/ngtcp2/ngtcp2/lib/ngtcp2_buf.h
vendored
8
deps/ngtcp2/ngtcp2/lib/ngtcp2_buf.h
vendored
|
@ -62,13 +62,17 @@ void ngtcp2_buf_reset(ngtcp2_buf *buf);
|
|||
* written to the underlying buffer. In other words, it returns
|
||||
* buf->end - buf->last.
|
||||
*/
|
||||
#define ngtcp2_buf_left(BUF) (size_t)((BUF)->end - (BUF)->last)
|
||||
static inline size_t ngtcp2_buf_left(const ngtcp2_buf *buf) {
|
||||
return (size_t)(buf->end - buf->last);
|
||||
}
|
||||
|
||||
/*
|
||||
* ngtcp2_buf_len returns the number of bytes left to read. In other
|
||||
* words, it returns buf->last - buf->pos.
|
||||
*/
|
||||
#define ngtcp2_buf_len(BUF) (size_t)((BUF)->last - (BUF)->pos)
|
||||
static inline size_t ngtcp2_buf_len(const ngtcp2_buf *buf) {
|
||||
return (size_t)(buf->last - buf->pos);
|
||||
}
|
||||
|
||||
/*
|
||||
* ngtcp2_buf_cap returns the capacity of the buffer. In other words,
|
||||
|
|
72
deps/ngtcp2/ngtcp2/lib/ngtcp2_callbacks.c
vendored
Normal file
72
deps/ngtcp2/ngtcp2/lib/ngtcp2_callbacks.c
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* ngtcp2
|
||||
*
|
||||
* Copyright (c) 2025 ngtcp2 contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "ngtcp2_callbacks.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "ngtcp2_unreachable.h"
|
||||
|
||||
static void callbacks_copy(ngtcp2_callbacks *dest, const ngtcp2_callbacks *src,
|
||||
int callbacks_version) {
|
||||
assert(callbacks_version != NGTCP2_CALLBACKS_VERSION);
|
||||
|
||||
memcpy(dest, src, ngtcp2_callbackslen_version(callbacks_version));
|
||||
}
|
||||
|
||||
const ngtcp2_callbacks *ngtcp2_callbacks_convert_to_latest(
|
||||
ngtcp2_callbacks *dest, int callbacks_version, const ngtcp2_callbacks *src) {
|
||||
if (callbacks_version == NGTCP2_CALLBACKS_VERSION) {
|
||||
return src;
|
||||
}
|
||||
|
||||
memset(dest, 0, sizeof(*dest));
|
||||
|
||||
callbacks_copy(dest, src, callbacks_version);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void ngtcp2_callbacks_convert_to_old(int callbacks_version,
|
||||
ngtcp2_callbacks *dest,
|
||||
const ngtcp2_callbacks *src) {
|
||||
assert(callbacks_version != NGTCP2_CALLBACKS_VERSION);
|
||||
|
||||
callbacks_copy(dest, src, callbacks_version);
|
||||
}
|
||||
|
||||
size_t ngtcp2_callbackslen_version(int callbacks_version) {
|
||||
ngtcp2_callbacks callbacks;
|
||||
|
||||
switch (callbacks_version) {
|
||||
case NGTCP2_CALLBACKS_VERSION:
|
||||
return sizeof(callbacks);
|
||||
case NGTCP2_CALLBACKS_V1:
|
||||
return offsetof(ngtcp2_callbacks, tls_early_data_rejected) +
|
||||
sizeof(callbacks.tls_early_data_rejected);
|
||||
default:
|
||||
ngtcp2_unreachable();
|
||||
}
|
||||
}
|
73
deps/ngtcp2/ngtcp2/lib/ngtcp2_callbacks.h
vendored
Normal file
73
deps/ngtcp2/ngtcp2/lib/ngtcp2_callbacks.h
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* ngtcp2
|
||||
*
|
||||
* Copyright (c) 2025 ngtcp2 contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGTCP2_CALLBACKS_H
|
||||
#define NGTCP2_CALLBACKS_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <ngtcp2/ngtcp2.h>
|
||||
|
||||
/*
|
||||
* ngtcp2_callbacks_convert_to_latest converts |src| of version
|
||||
* |callbacks_version| to the latest version NGTCP2_CALLBACKS_VERSION.
|
||||
*
|
||||
* |dest| must point to the latest version. |src| may be the older
|
||||
* version, and if so, it may have fewer fields. Accessing those
|
||||
* fields causes undefined behavior.
|
||||
*
|
||||
* If |callbacks_version| == NGTCP2_CALLBACKS_VERSION, no conversion
|
||||
* is made, and |src| is returned. Otherwise, first |dest| is
|
||||
* zero-initialized, and then all valid fields in |src| are copied
|
||||
* into |dest|. Finally, |dest| is returned.
|
||||
*/
|
||||
const ngtcp2_callbacks *ngtcp2_callbacks_convert_to_latest(
|
||||
ngtcp2_callbacks *dest, int callbacks_version, const ngtcp2_callbacks *src);
|
||||
|
||||
/*
|
||||
* ngtcp2_callbacks_convert_to_old converts |src| of the latest
|
||||
* version to |dest| of version |callbacks_version|.
|
||||
*
|
||||
* |callbacks_version| must not be the latest version
|
||||
* NGTCP2_CALLBACKS_VERSION.
|
||||
*
|
||||
* |dest| points to the older version, and it may have fewer fields.
|
||||
* Accessing those fields causes undefined behavior.
|
||||
*
|
||||
* This function copies all valid fields in version
|
||||
* |callbacks_version| from |src| to |dest|.
|
||||
*/
|
||||
void ngtcp2_callbacks_convert_to_old(int callbacks_version,
|
||||
ngtcp2_callbacks *dest,
|
||||
const ngtcp2_callbacks *src);
|
||||
|
||||
/*
|
||||
* ngtcp2_callbackslen_version returns the effective length of
|
||||
* ngtcp2_callbacks at the version |callbacks_version|.
|
||||
*/
|
||||
size_t ngtcp2_callbackslen_version(int callbacks_version);
|
||||
|
||||
#endif /* !defined(NGTCP2_CALLBACKS_H) */
|
162
deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c
vendored
162
deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c
vendored
|
@ -59,14 +59,16 @@ ngtcp2_cc_pkt *ngtcp2_cc_pkt_init(ngtcp2_cc_pkt *pkt, int64_t pkt_num,
|
|||
static void reno_cc_reset(ngtcp2_cc_reno *reno) { reno->pending_add = 0; }
|
||||
|
||||
void ngtcp2_cc_reno_init(ngtcp2_cc_reno *reno, ngtcp2_log *log) {
|
||||
memset(reno, 0, sizeof(*reno));
|
||||
|
||||
reno->cc.log = log;
|
||||
reno->cc.on_pkt_acked = ngtcp2_cc_reno_cc_on_pkt_acked;
|
||||
reno->cc.congestion_event = ngtcp2_cc_reno_cc_congestion_event;
|
||||
reno->cc.on_persistent_congestion =
|
||||
ngtcp2_cc_reno_cc_on_persistent_congestion;
|
||||
reno->cc.reset = ngtcp2_cc_reno_cc_reset;
|
||||
*reno = (ngtcp2_cc_reno){
|
||||
.cc =
|
||||
{
|
||||
.log = log,
|
||||
.on_pkt_acked = ngtcp2_cc_reno_cc_on_pkt_acked,
|
||||
.congestion_event = ngtcp2_cc_reno_cc_congestion_event,
|
||||
.on_persistent_congestion = ngtcp2_cc_reno_cc_on_persistent_congestion,
|
||||
.reset = ngtcp2_cc_reno_cc_reset,
|
||||
},
|
||||
};
|
||||
|
||||
reno_cc_reset(reno);
|
||||
}
|
||||
|
@ -148,11 +150,10 @@ void ngtcp2_cc_reno_cc_reset(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
static void cubic_vars_reset(ngtcp2_cubic_vars *v) {
|
||||
v->cwnd_prior = 0;
|
||||
v->w_max = 0;
|
||||
v->k = 0;
|
||||
v->k_m = 0;
|
||||
v->epoch_start = UINT64_MAX;
|
||||
v->w_est = 0;
|
||||
|
||||
v->state = NGTCP2_CUBIC_STATE_INITIAL;
|
||||
v->app_limited_start_ts = UINT64_MAX;
|
||||
v->app_limited_duration = 0;
|
||||
v->pending_bytes_delivered = 0;
|
||||
|
@ -177,17 +178,18 @@ static void cubic_cc_reset(ngtcp2_cc_cubic *cubic) {
|
|||
|
||||
void ngtcp2_cc_cubic_init(ngtcp2_cc_cubic *cubic, ngtcp2_log *log,
|
||||
ngtcp2_rst *rst) {
|
||||
memset(cubic, 0, sizeof(*cubic));
|
||||
|
||||
cubic->cc.log = log;
|
||||
cubic->cc.on_ack_recv = ngtcp2_cc_cubic_cc_on_ack_recv;
|
||||
cubic->cc.congestion_event = ngtcp2_cc_cubic_cc_congestion_event;
|
||||
cubic->cc.on_spurious_congestion = ngtcp2_cc_cubic_cc_on_spurious_congestion;
|
||||
cubic->cc.on_persistent_congestion =
|
||||
ngtcp2_cc_cubic_cc_on_persistent_congestion;
|
||||
cubic->cc.reset = ngtcp2_cc_cubic_cc_reset;
|
||||
|
||||
cubic->rst = rst;
|
||||
*cubic = (ngtcp2_cc_cubic){
|
||||
.cc =
|
||||
{
|
||||
.log = log,
|
||||
.on_ack_recv = ngtcp2_cc_cubic_cc_on_ack_recv,
|
||||
.congestion_event = ngtcp2_cc_cubic_cc_congestion_event,
|
||||
.on_spurious_congestion = ngtcp2_cc_cubic_cc_on_spurious_congestion,
|
||||
.on_persistent_congestion = ngtcp2_cc_cubic_cc_on_persistent_congestion,
|
||||
.reset = ngtcp2_cc_cubic_cc_reset,
|
||||
},
|
||||
.rst = rst,
|
||||
};
|
||||
|
||||
cubic_cc_reset(cubic);
|
||||
}
|
||||
|
@ -228,28 +230,42 @@ static uint64_t cubic_cc_compute_w_cubic(ngtcp2_cc_cubic *cubic,
|
|||
const ngtcp2_conn_stat *cstat,
|
||||
ngtcp2_tstamp ts) {
|
||||
ngtcp2_duration t = ts - cubic->current.epoch_start;
|
||||
uint64_t tx_m = (t << 10) / NGTCP2_SECONDS;
|
||||
int neg = tx_m < cubic->current.k_m;
|
||||
uint64_t time_delta_m;
|
||||
uint64_t delta;
|
||||
uint64_t tx = (t << 10) / NGTCP2_SECONDS;
|
||||
uint64_t kx = (cubic->current.k << 10) / NGTCP2_SECONDS;
|
||||
uint64_t time_delta;
|
||||
|
||||
if (tx < kx) {
|
||||
return UINT64_MAX;
|
||||
/* Avoid signed bit-shift */
|
||||
if (neg) {
|
||||
time_delta_m = cubic->current.k_m - tx_m;
|
||||
} else {
|
||||
time_delta_m = tx_m - cubic->current.k_m;
|
||||
}
|
||||
|
||||
time_delta = tx - kx;
|
||||
time_delta_m = ngtcp2_min_uint64(time_delta_m, 3600 << 10);
|
||||
|
||||
delta = cstat->max_tx_udp_payload_size *
|
||||
((((time_delta * time_delta) >> 10) * time_delta) >> 10) * 4 / 10;
|
||||
delta = ((((time_delta_m * time_delta_m) >> 10) * time_delta_m) >> 10) *
|
||||
cstat->max_tx_udp_payload_size * 4 / 10;
|
||||
delta >>= 10;
|
||||
|
||||
return cubic->current.w_max + (delta >> 10);
|
||||
if (neg) {
|
||||
if (cubic->current.w_max < delta) {
|
||||
/* Negative w_cubic is not interesting. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cubic->current.w_max - delta;
|
||||
}
|
||||
|
||||
return cubic->current.w_max + delta;
|
||||
}
|
||||
|
||||
void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
||||
const ngtcp2_cc_ack *ack,
|
||||
ngtcp2_tstamp ts) {
|
||||
ngtcp2_cc_cubic *cubic = ngtcp2_struct_of(cc, ngtcp2_cc_cubic, cc);
|
||||
uint64_t w_cubic, w_cubic_next, target, m;
|
||||
uint64_t w_cubic, w_cubic_next;
|
||||
uint64_t target, m;
|
||||
ngtcp2_duration rtt_thresh;
|
||||
int round_start;
|
||||
int is_app_limited =
|
||||
|
@ -259,24 +275,8 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
return;
|
||||
}
|
||||
|
||||
if (cubic->current.state == NGTCP2_CUBIC_STATE_CONGESTION_AVOIDANCE) {
|
||||
if (is_app_limited) {
|
||||
if (cubic->current.app_limited_start_ts == UINT64_MAX) {
|
||||
cubic->current.app_limited_start_ts = ts;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (cubic->current.app_limited_start_ts != UINT64_MAX) {
|
||||
cubic->current.app_limited_duration +=
|
||||
ts - cubic->current.app_limited_start_ts;
|
||||
cubic->current.app_limited_start_ts = UINT64_MAX;
|
||||
}
|
||||
} else if (is_app_limited) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cstat->cwnd < cstat->ssthresh) {
|
||||
/* slow-start */
|
||||
round_start = ack->pkt_delivered >= cubic->next_round_delivered;
|
||||
if (round_start) {
|
||||
cubic->next_round_delivered = cubic->rst->delivered;
|
||||
|
@ -284,8 +284,7 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
cubic->rst->is_cwnd_limited = 0;
|
||||
}
|
||||
|
||||
if (cstat->cwnd < cstat->ssthresh) {
|
||||
/* slow-start */
|
||||
if (!is_app_limited) {
|
||||
if (cubic->hs.css_round) {
|
||||
cstat->cwnd += ack->bytes_delivered / NGTCP2_HS_CSS_GROWTH_DIVISOR;
|
||||
} else {
|
||||
|
@ -295,6 +294,7 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
ngtcp2_log_info(cubic->cc.log, NGTCP2_LOG_EVENT_CCA,
|
||||
"%" PRIu64 " bytes acked, slow start cwnd=%" PRIu64,
|
||||
ack->bytes_delivered, cstat->cwnd);
|
||||
}
|
||||
|
||||
if (round_start) {
|
||||
cubic->hs.last_round_min_rtt = cubic->hs.current_round_min_rtt;
|
||||
|
@ -321,7 +321,11 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
ngtcp2_log_info(cubic->cc.log, NGTCP2_LOG_EVENT_CCA,
|
||||
"HyStart++ exit slow start");
|
||||
|
||||
cubic->current.epoch_start = ts;
|
||||
cubic->current.w_max = cstat->cwnd;
|
||||
cstat->ssthresh = cstat->cwnd;
|
||||
cubic->current.cwnd_prior = cstat->cwnd;
|
||||
cubic->current.w_est = cstat->cwnd;
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -347,20 +351,18 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
}
|
||||
|
||||
/* congestion avoidance */
|
||||
if (is_app_limited) {
|
||||
if (cubic->current.app_limited_start_ts == UINT64_MAX) {
|
||||
cubic->current.app_limited_start_ts = ts;
|
||||
}
|
||||
|
||||
switch (cubic->current.state) {
|
||||
case NGTCP2_CUBIC_STATE_INITIAL:
|
||||
m = cstat->max_tx_udp_payload_size * ack->bytes_delivered +
|
||||
cubic->current.pending_bytes_delivered;
|
||||
cstat->cwnd += m / cstat->cwnd;
|
||||
cubic->current.pending_bytes_delivered = m % cstat->cwnd;
|
||||
return;
|
||||
case NGTCP2_CUBIC_STATE_RECOVERY:
|
||||
cubic->current.state = NGTCP2_CUBIC_STATE_CONGESTION_AVOIDANCE;
|
||||
cubic->current.epoch_start = ts;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (cubic->current.app_limited_start_ts != UINT64_MAX) {
|
||||
cubic->current.app_limited_duration +=
|
||||
ts - cubic->current.app_limited_start_ts;
|
||||
cubic->current.app_limited_start_ts = UINT64_MAX;
|
||||
}
|
||||
|
||||
w_cubic = cubic_cc_compute_w_cubic(cubic, cstat,
|
||||
|
@ -369,7 +371,7 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
cubic, cstat,
|
||||
ts - cubic->current.app_limited_duration + cstat->smoothed_rtt);
|
||||
|
||||
if (w_cubic_next == UINT64_MAX || w_cubic_next < cstat->cwnd) {
|
||||
if (w_cubic_next < cstat->cwnd) {
|
||||
target = cstat->cwnd;
|
||||
} else if (2 * w_cubic_next > 3 * cstat->cwnd) {
|
||||
target = cstat->cwnd * 3 / 2;
|
||||
|
@ -387,19 +389,19 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
cubic->current.w_est += m / cstat->cwnd;
|
||||
}
|
||||
|
||||
if (w_cubic == UINT64_MAX || cubic->current.w_est > w_cubic) {
|
||||
if (cubic->current.w_est > w_cubic) {
|
||||
cstat->cwnd = cubic->current.w_est;
|
||||
} else {
|
||||
m = (target - cstat->cwnd) * cstat->max_tx_udp_payload_size +
|
||||
cubic->current.pending_bytes_delivered;
|
||||
cstat->cwnd += m / cstat->cwnd;
|
||||
cubic->current.pending_bytes_delivered = m % cstat->cwnd;
|
||||
cstat->cwnd += m / cstat->cwnd;
|
||||
}
|
||||
|
||||
ngtcp2_log_info(cubic->cc.log, NGTCP2_LOG_EVENT_CCA,
|
||||
"%" PRIu64 " bytes acked, cubic-ca cwnd=%" PRIu64
|
||||
" k=%" PRIi64 " target=%" PRIu64 " w_est=%" PRIu64,
|
||||
ack->bytes_delivered, cstat->cwnd, cubic->current.k, target,
|
||||
" k_m=%" PRIu64 " target=%" PRIu64 " w_est=%" PRIu64,
|
||||
ack->bytes_delivered, cstat->cwnd, cubic->current.k_m, target,
|
||||
cubic->current.w_est);
|
||||
}
|
||||
|
||||
|
@ -409,6 +411,7 @@ void ngtcp2_cc_cubic_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
ngtcp2_tstamp ts) {
|
||||
ngtcp2_cc_cubic *cubic = ngtcp2_struct_of(cc, ngtcp2_cc_cubic, cc);
|
||||
uint64_t flight_size;
|
||||
uint64_t cwnd_delta;
|
||||
|
||||
if (in_congestion_recovery(cstat, sent_ts)) {
|
||||
return;
|
||||
|
@ -422,8 +425,7 @@ void ngtcp2_cc_cubic_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
|
||||
cstat->congestion_recovery_start_ts = ts;
|
||||
|
||||
cubic->current.state = NGTCP2_CUBIC_STATE_RECOVERY;
|
||||
cubic->current.epoch_start = UINT64_MAX;
|
||||
cubic->current.epoch_start = ts;
|
||||
cubic->current.app_limited_start_ts = UINT64_MAX;
|
||||
cubic->current.app_limited_duration = 0;
|
||||
cubic->current.pending_bytes_delivered = 0;
|
||||
|
@ -435,13 +437,16 @@ void ngtcp2_cc_cubic_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
cubic->current.w_max = cstat->cwnd;
|
||||
}
|
||||
|
||||
cubic->current.w_max =
|
||||
ngtcp2_max_uint64(cubic->current.w_max, 2 * cstat->max_tx_udp_payload_size);
|
||||
|
||||
cstat->ssthresh = cstat->cwnd * 7 / 10;
|
||||
|
||||
if (cubic->rst->rs.delivered * 2 < cstat->cwnd) {
|
||||
flight_size = cstat->bytes_in_flight + bytes_lost;
|
||||
cstat->ssthresh = ngtcp2_min_uint64(
|
||||
cstat->ssthresh,
|
||||
ngtcp2_max_uint64(cubic->rst->rs.delivered, flight_size) * 7 / 10);
|
||||
ngtcp2_max_uint64(cubic->rst->rs.delivered, flight_size));
|
||||
}
|
||||
|
||||
cstat->ssthresh =
|
||||
|
@ -452,15 +457,12 @@ void ngtcp2_cc_cubic_cc_congestion_event(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
|||
|
||||
cubic->current.w_est = cstat->cwnd;
|
||||
|
||||
if (cstat->cwnd < cubic->current.w_max) {
|
||||
cubic->current.k =
|
||||
ngtcp2_cbrt(((cubic->current.w_max - cstat->cwnd) << 10) * 10 / 4 /
|
||||
cstat->max_tx_udp_payload_size) *
|
||||
NGTCP2_SECONDS;
|
||||
cubic->current.k >>= 10;
|
||||
} else {
|
||||
cubic->current.k = 0;
|
||||
}
|
||||
assert(cubic->current.w_max >= cstat->cwnd);
|
||||
|
||||
cwnd_delta = cubic->current.w_max - cstat->cwnd;
|
||||
|
||||
cubic->current.k_m =
|
||||
ngtcp2_cbrt((cwnd_delta << 30) * 10 / 4 / cstat->max_tx_udp_payload_size);
|
||||
|
||||
ngtcp2_log_info(cubic->cc.log, NGTCP2_LOG_EVENT_CCA,
|
||||
"reduce cwnd because of packet loss cwnd=%" PRIu64,
|
||||
|
|
17
deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.h
vendored
17
deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.h
vendored
|
@ -326,27 +326,14 @@ void ngtcp2_cc_reno_cc_on_persistent_congestion(ngtcp2_cc *cc,
|
|||
void ngtcp2_cc_reno_cc_reset(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
||||
ngtcp2_tstamp ts);
|
||||
|
||||
typedef enum ngtcp2_cubic_state {
|
||||
/* NGTCP2_CUBIC_STATE_INITIAL is the state where CUBIC is in slow
|
||||
start phase, or congestion avoidance phase before congestion
|
||||
events occur. */
|
||||
NGTCP2_CUBIC_STATE_INITIAL,
|
||||
/* NGTCP2_CUBIC_STATE_RECOVERY is the state that a connection is in
|
||||
recovery period. */
|
||||
NGTCP2_CUBIC_STATE_RECOVERY,
|
||||
/* NGTCP2_CUBIC_STATE_CONGESTION_AVOIDANCE is the state where CUBIC
|
||||
is in congestion avoidance phase after recovery period ends. */
|
||||
NGTCP2_CUBIC_STATE_CONGESTION_AVOIDANCE,
|
||||
} ngtcp2_cubic_state;
|
||||
|
||||
typedef struct ngtcp2_cubic_vars {
|
||||
uint64_t cwnd_prior;
|
||||
uint64_t w_max;
|
||||
ngtcp2_duration k;
|
||||
/* CUBIC K with 10 bits extra precision. */
|
||||
uint64_t k_m;
|
||||
ngtcp2_tstamp epoch_start;
|
||||
uint64_t w_est;
|
||||
|
||||
ngtcp2_cubic_state state;
|
||||
/* app_limited_start_ts is the timestamp where app limited period
|
||||
started. */
|
||||
ngtcp2_tstamp app_limited_start_ts;
|
||||
|
|
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_cid.c
vendored
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_cid.c
vendored
|
@ -149,3 +149,9 @@ int ngtcp2_dcid_verify_stateless_reset_token(const ngtcp2_dcid *dcid,
|
|||
? 0
|
||||
: NGTCP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
void ngtcp2_dcid_apply_validated_path(ngtcp2_dcid *dcid,
|
||||
const ngtcp2_path_history_entry *ent) {
|
||||
dcid->flags |= NGTCP2_DCID_FLAG_PATH_VALIDATED;
|
||||
dcid->max_udp_payload_size = ent->max_udp_payload_size;
|
||||
}
|
||||
|
|
20
deps/ngtcp2/ngtcp2/lib/ngtcp2_cid.h
vendored
20
deps/ngtcp2/ngtcp2/lib/ngtcp2_cid.h
vendored
|
@ -176,4 +176,24 @@ int ngtcp2_dcid_verify_stateless_reset_token(const ngtcp2_dcid *dcid,
|
|||
const ngtcp2_path *path,
|
||||
const uint8_t *token);
|
||||
|
||||
/* TODO It might be performance win if we store congestion state in
|
||||
this entry, and restore it when migrate back to this path. */
|
||||
typedef struct ngtcp2_path_history_entry {
|
||||
/* ps contains path. */
|
||||
ngtcp2_path_storage ps;
|
||||
/* max_udp_payload_size is the maximum size of UDP datagram payload
|
||||
that is allowed to be sent to this path. */
|
||||
size_t max_udp_payload_size;
|
||||
/* ts is the timestamp when this entry is added to the path history.
|
||||
It happens when a local endpoint migrates to the another path. */
|
||||
ngtcp2_tstamp ts;
|
||||
} ngtcp2_path_history_entry;
|
||||
|
||||
/*
|
||||
* ngtcp2_dcid_apply_validated_path applies the defaults from |ent|
|
||||
* which contains the validated path and its stored configurations.
|
||||
*/
|
||||
void ngtcp2_dcid_apply_validated_path(ngtcp2_dcid *dcid,
|
||||
const ngtcp2_path_history_entry *ent);
|
||||
|
||||
#endif /* !defined(NGTCP2_CID_H) */
|
||||
|
|
501
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c
vendored
501
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c
vendored
File diff suppressed because it is too large
Load diff
26
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.h
vendored
26
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.h
vendored
|
@ -110,6 +110,9 @@ typedef enum {
|
|||
NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING, but it requests to add
|
||||
padding to the full UDP datagram payload size. */
|
||||
#define NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING_FULL 0x04u
|
||||
/* NGTCP2_WRITE_PKT_FLAG_PADDING_IF_NOT_EMPTY adds padding to the QUIC
|
||||
packet as much as possible if the packet is not empty. */
|
||||
#define NGTCP2_WRITE_PKT_FLAG_PADDING_IF_NOT_EMPTY 0x08u
|
||||
|
||||
/*
|
||||
* ngtcp2_max_frame is defined so that it covers the largest ACK
|
||||
|
@ -203,6 +206,13 @@ typedef struct ngtcp2_pktns {
|
|||
/* last_pkt_num is the packet number which the local endpoint sent
|
||||
last time.*/
|
||||
int64_t last_pkt_num;
|
||||
struct {
|
||||
/* next_pkt_num is the next packet number to skip. */
|
||||
int64_t next_pkt_num;
|
||||
/* exponent makes gap of skipping packets spread
|
||||
exponentially. */
|
||||
int64_t exponent;
|
||||
} skip_pkt;
|
||||
ngtcp2_frame_chain *frq;
|
||||
/* non_ack_pkt_start_ts is the timestamp since the local endpoint
|
||||
starts sending continuous non ACK-eliciting packets. */
|
||||
|
@ -308,6 +318,8 @@ typedef struct ngtcp2_early_transport_params {
|
|||
ngtcp2_static_ringbuf_def(path_challenge, 4,
|
||||
sizeof(ngtcp2_path_challenge_entry))
|
||||
|
||||
ngtcp2_static_ringbuf_def(path_history, 4, sizeof(ngtcp2_path_history_entry))
|
||||
|
||||
ngtcp2_objalloc_decl(strm, ngtcp2_strm, oplent)
|
||||
|
||||
struct ngtcp2_conn {
|
||||
|
@ -625,6 +637,10 @@ struct ngtcp2_conn {
|
|||
ngtcp2_cc_cubic cubic;
|
||||
ngtcp2_cc_bbr bbr;
|
||||
};
|
||||
/* path_history remembers the paths that have been validated
|
||||
successfully. The path is added to this history when a local
|
||||
endpoint migrates to the another path. */
|
||||
ngtcp2_static_ringbuf_path_history path_history;
|
||||
const ngtcp2_mem *mem;
|
||||
/* idle_ts is the time instant when idle timer started. */
|
||||
ngtcp2_tstamp idle_ts;
|
||||
|
@ -801,7 +817,8 @@ ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn);
|
|||
ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
|
||||
int pkt_info_version, ngtcp2_pkt_info *pi,
|
||||
uint8_t *dest, size_t destlen,
|
||||
ngtcp2_vmsg *vmsg, ngtcp2_tstamp ts);
|
||||
uint8_t wflags, ngtcp2_vmsg *vmsg,
|
||||
ngtcp2_tstamp ts);
|
||||
|
||||
/*
|
||||
* ngtcp2_conn_write_single_frame_pkt writes a packet which contains
|
||||
|
@ -1094,4 +1111,11 @@ void ngtcp2_conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts);
|
|||
*/
|
||||
void ngtcp2_conn_discard_handshake_state(ngtcp2_conn *conn, ngtcp2_tstamp ts);
|
||||
|
||||
void ngtcp2_conn_add_path_history(ngtcp2_conn *conn, const ngtcp2_dcid *dcid,
|
||||
ngtcp2_tstamp ts);
|
||||
|
||||
const ngtcp2_path_history_entry *
|
||||
ngtcp2_conn_find_path_history(ngtcp2_conn *conn, const ngtcp2_path *path,
|
||||
ngtcp2_tstamp ts);
|
||||
|
||||
#endif /* !defined(NGTCP2_CONN_H) */
|
||||
|
|
8
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h
vendored
8
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn_stat.h
vendored
|
@ -116,13 +116,13 @@ typedef struct ngtcp2_conn_stat {
|
|||
*/
|
||||
uint64_t delivery_rate_sec;
|
||||
/**
|
||||
* :member:`pacing_interval` is the inverse of pacing rate, which is
|
||||
* the current packet sending rate computed by a congestion
|
||||
* :member:`pacing_interval_m` is the inverse of pacing rate, which
|
||||
* is the current packet sending rate computed by a congestion
|
||||
* controller. 0 if a congestion controller does not set pacing
|
||||
* interval. Even if this value is set to 0, the library paces
|
||||
* packets.
|
||||
* packets. The unit of this value is 1/1024 of nanoseconds.
|
||||
*/
|
||||
ngtcp2_duration pacing_interval;
|
||||
uint64_t pacing_interval_m;
|
||||
/**
|
||||
* :member:`send_quantum` is the maximum size of a data aggregate
|
||||
* scheduled and transmitted together.
|
||||
|
|
16
deps/ngtcp2/ngtcp2/lib/ngtcp2_dcidtr.c
vendored
16
deps/ngtcp2/ngtcp2/lib/ngtcp2_dcidtr.c
vendored
|
@ -157,10 +157,11 @@ int ngtcp2_dcidtr_bind_dcid(ngtcp2_dcidtr *dtr, ngtcp2_dcid **pdest,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int verify_stateless_reset(const ngtcp2_ringbuf *rb,
|
||||
int ngtcp2_dcidtr_verify_stateless_reset(const ngtcp2_dcidtr *dtr,
|
||||
const ngtcp2_path *path,
|
||||
const uint8_t *token) {
|
||||
const ngtcp2_dcid *dcid;
|
||||
const ngtcp2_ringbuf *rb = &dtr->bound.rb;
|
||||
size_t i, len = ngtcp2_ringbuf_len(rb);
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
|
@ -173,19 +174,6 @@ static int verify_stateless_reset(const ngtcp2_ringbuf *rb,
|
|||
return NGTCP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
int ngtcp2_dcidtr_verify_stateless_reset(const ngtcp2_dcidtr *dtr,
|
||||
const ngtcp2_path *path,
|
||||
const uint8_t *token) {
|
||||
int rv;
|
||||
|
||||
rv = verify_stateless_reset(&dtr->retired.rb, path, token);
|
||||
if (rv == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return verify_stateless_reset(&dtr->bound.rb, path, token);
|
||||
}
|
||||
|
||||
static int verify_token_uniqueness(const ngtcp2_ringbuf *rb, int *pfound,
|
||||
uint64_t seq, const ngtcp2_cid *cid,
|
||||
const uint8_t *token) {
|
||||
|
|
2
deps/ngtcp2/ngtcp2/lib/ngtcp2_dcidtr.h
vendored
2
deps/ngtcp2/ngtcp2/lib/ngtcp2_dcidtr.h
vendored
|
@ -340,4 +340,4 @@ int ngtcp2_dcidtr_unused_empty(const ngtcp2_dcidtr *dtr);
|
|||
*/
|
||||
int ngtcp2_dcidtr_bound_full(const ngtcp2_dcidtr *dtr);
|
||||
|
||||
#endif /* NGTCP2_DCIDTR_H */
|
||||
#endif /* !defined(NGTCP2_DCIDTR_H) */
|
||||
|
|
32
deps/ngtcp2/ngtcp2/lib/ngtcp2_ksl.h
vendored
32
deps/ngtcp2/ngtcp2/lib/ngtcp2_ksl.h
vendored
|
@ -292,8 +292,11 @@ void ngtcp2_ksl_clear(ngtcp2_ksl *ksl);
|
|||
/*
|
||||
* ngtcp2_ksl_nth_node returns the |n|th node under |blk|.
|
||||
*/
|
||||
#define ngtcp2_ksl_nth_node(KSL, BLK, N) \
|
||||
((ngtcp2_ksl_node *)(void *)((BLK)->nodes + (KSL)->nodelen * (N)))
|
||||
static inline ngtcp2_ksl_node *ngtcp2_ksl_nth_node(const ngtcp2_ksl *ksl,
|
||||
const ngtcp2_ksl_blk *blk,
|
||||
size_t n) {
|
||||
return (ngtcp2_ksl_node *)(void *)(blk->nodes + ksl->nodelen * n);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
/*
|
||||
|
@ -315,18 +318,21 @@ void ngtcp2_ksl_it_init(ngtcp2_ksl_it *it, const ngtcp2_ksl *ksl,
|
|||
* |it| points to. It is undefined to call this function when
|
||||
* ngtcp2_ksl_it_end(it) returns nonzero.
|
||||
*/
|
||||
#define ngtcp2_ksl_it_get(IT) \
|
||||
ngtcp2_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->data
|
||||
static inline void *ngtcp2_ksl_it_get(const ngtcp2_ksl_it *it) {
|
||||
return ngtcp2_ksl_nth_node(it->ksl, it->blk, it->i)->data;
|
||||
}
|
||||
|
||||
/*
|
||||
* ngtcp2_ksl_it_next advances the iterator by one. It is undefined
|
||||
* if this function is called when ngtcp2_ksl_it_end(it) returns
|
||||
* nonzero.
|
||||
*/
|
||||
#define ngtcp2_ksl_it_next(IT) \
|
||||
(++(IT)->i == (IT)->blk->n && (IT)->blk->next \
|
||||
? ((IT)->blk = (IT)->blk->next, (IT)->i = 0) \
|
||||
: 0)
|
||||
static inline void ngtcp2_ksl_it_next(ngtcp2_ksl_it *it) {
|
||||
if (++it->i == it->blk->n && it->blk->next) {
|
||||
it->blk = it->blk->next;
|
||||
it->i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ngtcp2_ksl_it_prev moves backward the iterator by one. It is
|
||||
|
@ -339,8 +345,9 @@ void ngtcp2_ksl_it_prev(ngtcp2_ksl_it *it);
|
|||
* ngtcp2_ksl_it_end returns nonzero if |it| points to the one beyond
|
||||
* the last node.
|
||||
*/
|
||||
#define ngtcp2_ksl_it_end(IT) \
|
||||
((IT)->blk->n == (IT)->i && (IT)->blk->next == NULL)
|
||||
static inline int ngtcp2_ksl_it_end(const ngtcp2_ksl_it *it) {
|
||||
return it->blk->n == it->i && it->blk->next == NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ngtcp2_ksl_it_begin returns nonzero if |it| points to the first
|
||||
|
@ -354,8 +361,9 @@ int ngtcp2_ksl_it_begin(const ngtcp2_ksl_it *it);
|
|||
* It is undefined to call this function when ngtcp2_ksl_it_end(it)
|
||||
* returns nonzero.
|
||||
*/
|
||||
#define ngtcp2_ksl_it_key(IT) \
|
||||
((ngtcp2_ksl_key *)ngtcp2_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->key)
|
||||
static inline ngtcp2_ksl_key *ngtcp2_ksl_it_key(const ngtcp2_ksl_it *it) {
|
||||
return (ngtcp2_ksl_key *)ngtcp2_ksl_nth_node(it->ksl, it->blk, it->i)->key;
|
||||
}
|
||||
|
||||
/*
|
||||
* ngtcp2_ksl_range_compar is an implementation of ngtcp2_ksl_compar.
|
||||
|
|
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_log.c
vendored
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_log.c
vendored
|
@ -594,9 +594,9 @@ void ngtcp2_log_rx_sr(ngtcp2_log *log, const ngtcp2_pkt_stateless_reset *sr) {
|
|||
return;
|
||||
}
|
||||
|
||||
memset(&shd, 0, sizeof(shd));
|
||||
|
||||
shd.type = NGTCP2_PKT_STATELESS_RESET;
|
||||
shd = (ngtcp2_pkt_hd){
|
||||
.type = NGTCP2_PKT_STATELESS_RESET,
|
||||
};
|
||||
|
||||
log->log_printf(
|
||||
log->user_data, (NGTCP2_LOG_PKT " token=0x%s randlen=%zu"),
|
||||
|
|
57
deps/ngtcp2/ngtcp2/lib/ngtcp2_map.c
vendored
57
deps/ngtcp2/ngtcp2/lib/ngtcp2_map.c
vendored
|
@ -33,10 +33,11 @@
|
|||
|
||||
#define NGTCP2_INITIAL_HASHBITS 4
|
||||
|
||||
void ngtcp2_map_init(ngtcp2_map *map, const ngtcp2_mem *mem) {
|
||||
void ngtcp2_map_init(ngtcp2_map *map, uint64_t seed, const ngtcp2_mem *mem) {
|
||||
map->mem = mem;
|
||||
map->hashbits = 0;
|
||||
map->table = NULL;
|
||||
map->seed = seed;
|
||||
map->size = 0;
|
||||
}
|
||||
|
||||
|
@ -77,8 +78,14 @@ int ngtcp2_map_each(const ngtcp2_map *map, int (*func)(void *data, void *ptr),
|
|||
return 0;
|
||||
}
|
||||
|
||||
static size_t hash(ngtcp2_map_key_type key, size_t bits) {
|
||||
return (size_t)((key * 11400714819323198485llu) >> (64 - bits));
|
||||
static size_t map_hash(const ngtcp2_map *map, ngtcp2_map_key_type key) {
|
||||
/* hasher from
|
||||
https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs
|
||||
We do not perform finalization here because we use top bits
|
||||
anyway. */
|
||||
key += map->seed;
|
||||
key *= 0xf1357aea2e62a9c5ull;
|
||||
return (size_t)((key * 11400714819323198485llu) >> (64 - map->hashbits));
|
||||
}
|
||||
|
||||
static void map_bucket_swap(ngtcp2_map_bucket *a, ngtcp2_map_bucket *b) {
|
||||
|
@ -109,28 +116,28 @@ void ngtcp2_map_print_distance(const ngtcp2_map *map) {
|
|||
continue;
|
||||
}
|
||||
|
||||
idx = hash(bkt->key, map->hashbits);
|
||||
idx = map_hash(map, bkt->key);
|
||||
fprintf(stderr, "@%zu hash=%zu key=%" PRIu64 " base=%zu distance=%u\n", i,
|
||||
hash(bkt->key, map->hashbits), bkt->key, idx, bkt->psl);
|
||||
map_hash(map, bkt->key), bkt->key, idx, bkt->psl);
|
||||
}
|
||||
}
|
||||
#endif /* !defined(WIN32) */
|
||||
|
||||
static int insert(ngtcp2_map_bucket *table, size_t hashbits,
|
||||
ngtcp2_map_key_type key, void *data) {
|
||||
size_t idx = hash(key, hashbits);
|
||||
static int map_insert(ngtcp2_map *map, ngtcp2_map_key_type key, void *data) {
|
||||
size_t idx = map_hash(map, key);
|
||||
ngtcp2_map_bucket b = {
|
||||
.key = key,
|
||||
.data = data,
|
||||
};
|
||||
ngtcp2_map_bucket *bkt;
|
||||
size_t mask = (1u << hashbits) - 1;
|
||||
size_t mask = (1u << map->hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
bkt = &table[idx];
|
||||
bkt = &map->table[idx];
|
||||
|
||||
if (bkt->data == NULL) {
|
||||
*bkt = b;
|
||||
++map->size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -151,15 +158,19 @@ static int insert(ngtcp2_map_bucket *table, size_t hashbits,
|
|||
|
||||
static int map_resize(ngtcp2_map *map, size_t new_hashbits) {
|
||||
size_t i;
|
||||
ngtcp2_map_bucket *new_table;
|
||||
ngtcp2_map_bucket *bkt;
|
||||
size_t tablelen;
|
||||
int rv;
|
||||
ngtcp2_map new_map = {
|
||||
.table = ngtcp2_mem_calloc(map->mem, 1u << new_hashbits,
|
||||
sizeof(ngtcp2_map_bucket)),
|
||||
.mem = map->mem,
|
||||
.seed = map->seed,
|
||||
.hashbits = new_hashbits,
|
||||
};
|
||||
(void)rv;
|
||||
|
||||
new_table =
|
||||
ngtcp2_mem_calloc(map->mem, 1u << new_hashbits, sizeof(ngtcp2_map_bucket));
|
||||
if (new_table == NULL) {
|
||||
if (new_map.table == NULL) {
|
||||
return NGTCP2_ERR_NOMEM;
|
||||
}
|
||||
|
||||
|
@ -172,15 +183,15 @@ static int map_resize(ngtcp2_map *map, size_t new_hashbits) {
|
|||
continue;
|
||||
}
|
||||
|
||||
rv = insert(new_table, new_hashbits, bkt->key, bkt->data);
|
||||
rv = map_insert(&new_map, bkt->key, bkt->data);
|
||||
|
||||
assert(0 == rv);
|
||||
}
|
||||
}
|
||||
|
||||
ngtcp2_mem_free(map->mem, map->table);
|
||||
map->table = new_map.table;
|
||||
map->hashbits = new_hashbits;
|
||||
map->table = new_table;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -190,10 +201,10 @@ int ngtcp2_map_insert(ngtcp2_map *map, ngtcp2_map_key_type key, void *data) {
|
|||
|
||||
assert(data);
|
||||
|
||||
/* Load factor is 0.75 */
|
||||
/* Load factor is 7/8 */
|
||||
/* Under the very initial condition, that is map->size == 0 and
|
||||
map->hashbits == 0, 4 > 3 still holds nicely. */
|
||||
if ((map->size + 1) * 4 > (1u << map->hashbits) * 3) {
|
||||
map->hashbits == 0, 8 > 7 still holds nicely. */
|
||||
if ((map->size + 1) * 8 > (1u << map->hashbits) * 7) {
|
||||
if (map->hashbits) {
|
||||
rv = map_resize(map, map->hashbits + 1);
|
||||
if (rv != 0) {
|
||||
|
@ -207,13 +218,11 @@ int ngtcp2_map_insert(ngtcp2_map *map, ngtcp2_map_key_type key, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
rv = insert(map->table, map->hashbits, key, data);
|
||||
rv = map_insert(map, key, data);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
++map->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -227,7 +236,7 @@ void *ngtcp2_map_find(const ngtcp2_map *map, ngtcp2_map_key_type key) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
idx = hash(key, map->hashbits);
|
||||
idx = map_hash(map, key);
|
||||
mask = (1u << map->hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
|
@ -256,7 +265,7 @@ int ngtcp2_map_remove(ngtcp2_map *map, ngtcp2_map_key_type key) {
|
|||
return NGTCP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
idx = hash(key, map->hashbits);
|
||||
idx = map_hash(map, key);
|
||||
mask = (1u << map->hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
|
|
3
deps/ngtcp2/ngtcp2/lib/ngtcp2_map.h
vendored
3
deps/ngtcp2/ngtcp2/lib/ngtcp2_map.h
vendored
|
@ -47,6 +47,7 @@ typedef struct ngtcp2_map_bucket {
|
|||
typedef struct ngtcp2_map {
|
||||
ngtcp2_map_bucket *table;
|
||||
const ngtcp2_mem *mem;
|
||||
uint64_t seed;
|
||||
size_t size;
|
||||
size_t hashbits;
|
||||
} ngtcp2_map;
|
||||
|
@ -54,7 +55,7 @@ typedef struct ngtcp2_map {
|
|||
/*
|
||||
* ngtcp2_map_init initializes the map |map|.
|
||||
*/
|
||||
void ngtcp2_map_init(ngtcp2_map *map, const ngtcp2_mem *mem);
|
||||
void ngtcp2_map_init(ngtcp2_map *map, uint64_t seed, const ngtcp2_mem *mem);
|
||||
|
||||
/*
|
||||
* ngtcp2_map_free deallocates any resources allocated for |map|. The
|
||||
|
|
16
deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c
vendored
16
deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c
vendored
|
@ -304,11 +304,11 @@ ngtcp2_ssize ngtcp2_pkt_decode_hd_long(ngtcp2_pkt_hd *dest, const uint8_t *pkt,
|
|||
}
|
||||
|
||||
ngtcp2_get_uvarint(&vi, p);
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
#if SIZE_MAX < UINT64_MAX
|
||||
if (vi > SIZE_MAX) {
|
||||
return NGTCP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
#endif /* SIZE_MAX > UINT32_MAX */
|
||||
#endif /* SIZE_MAX < UINT64_MAX */
|
||||
|
||||
longlen = (size_t)vi;
|
||||
}
|
||||
|
@ -2080,8 +2080,10 @@ ngtcp2_ssize ngtcp2_pkt_encode_datagram_frame(uint8_t *out, size_t outlen,
|
|||
}
|
||||
|
||||
for (i = 0; i < fr->datacnt; ++i) {
|
||||
assert(fr->data[i].len);
|
||||
assert(fr->data[i].base);
|
||||
if (fr->data[i].len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
p = ngtcp2_cpymem(p, fr->data[i].base, fr->data[i].len);
|
||||
}
|
||||
|
||||
|
@ -2421,9 +2423,7 @@ size_t ngtcp2_pkt_stream_max_datalen(int64_t stream_id, uint64_t offset,
|
|||
left -= n;
|
||||
|
||||
if (left > 8 + 1073741823 && len > 1073741823) {
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
len = ngtcp2_min_uint64(len, 4611686018427387903lu);
|
||||
#endif /* SIZE_MAX > UINT32_MAX */
|
||||
return (size_t)ngtcp2_min_uint64(len, (uint64_t)(left - 8));
|
||||
}
|
||||
|
||||
|
@ -2453,9 +2453,9 @@ size_t ngtcp2_pkt_crypto_max_datalen(uint64_t offset, size_t len, size_t left) {
|
|||
left -= n;
|
||||
|
||||
if (left > 8 + 1073741823 && len > 1073741823) {
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
#if SIZE_MAX == UINT64_MAX
|
||||
len = ngtcp2_min_size(len, 4611686018427387903lu);
|
||||
#endif /* SIZE_MAX > UINT32_MAX */
|
||||
#endif /* SIZE_MAX == UINT64_MAX */
|
||||
return ngtcp2_min_size(len, left - 8);
|
||||
}
|
||||
|
||||
|
|
7
deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h
vendored
7
deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h
vendored
|
@ -137,6 +137,13 @@
|
|||
v2. */
|
||||
#define NGTCP2_PKT_TYPE_RETRY_V2 0x0
|
||||
|
||||
/* NGTCP2_MIN_STREAM_DATALEN is the minimum length of STREAM frame to
|
||||
avoid too small frame. It is not always enforced for various
|
||||
reasons. For example, due to flow control, we might have fewer
|
||||
bytes available to send. Therefore, it is only applied when the
|
||||
length of data to send is larger than this limit. */
|
||||
#define NGTCP2_MIN_STREAM_DATALEN 256
|
||||
|
||||
typedef struct ngtcp2_pkt_retry {
|
||||
ngtcp2_cid odcid;
|
||||
uint8_t *token;
|
||||
|
|
32
deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.c
vendored
32
deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.c
vendored
|
@ -47,9 +47,10 @@ void ngtcp2_ppe_init(ngtcp2_ppe *ppe, uint8_t *out, size_t outlen,
|
|||
int ngtcp2_ppe_encode_hd(ngtcp2_ppe *ppe, const ngtcp2_pkt_hd *hd) {
|
||||
ngtcp2_ssize rv;
|
||||
ngtcp2_buf *buf = &ppe->buf;
|
||||
size_t buf_left = ngtcp2_buf_left(buf);
|
||||
ngtcp2_crypto_cc *cc = ppe->cc;
|
||||
|
||||
if (ngtcp2_buf_left(buf) < cc->aead.max_overhead) {
|
||||
if (buf_left <= cc->aead.max_overhead) {
|
||||
return NGTCP2_ERR_NOBUF;
|
||||
}
|
||||
|
||||
|
@ -62,13 +63,13 @@ int ngtcp2_ppe_encode_hd(ngtcp2_ppe *ppe, const ngtcp2_pkt_hd *hd) {
|
|||
|
||||
ppe->pkt_num_offset = ppe->len_offset + NGTCP2_PKT_LENGTHLEN;
|
||||
|
||||
rv = ngtcp2_pkt_encode_hd_long(
|
||||
buf->last, ngtcp2_buf_left(buf) - cc->aead.max_overhead, hd);
|
||||
rv = ngtcp2_pkt_encode_hd_long(buf->last, buf_left - cc->aead.max_overhead,
|
||||
hd);
|
||||
} else {
|
||||
ppe->pkt_num_offset = 1 + hd->dcid.datalen;
|
||||
|
||||
rv = ngtcp2_pkt_encode_hd_short(
|
||||
buf->last, ngtcp2_buf_left(buf) - cc->aead.max_overhead, hd);
|
||||
rv = ngtcp2_pkt_encode_hd_short(buf->last, buf_left - cc->aead.max_overhead,
|
||||
hd);
|
||||
}
|
||||
|
||||
if (rv < 0) {
|
||||
|
@ -87,14 +88,14 @@ int ngtcp2_ppe_encode_hd(ngtcp2_ppe *ppe, const ngtcp2_pkt_hd *hd) {
|
|||
int ngtcp2_ppe_encode_frame(ngtcp2_ppe *ppe, ngtcp2_frame *fr) {
|
||||
ngtcp2_ssize rv;
|
||||
ngtcp2_buf *buf = &ppe->buf;
|
||||
size_t buf_left = ngtcp2_buf_left(buf);
|
||||
ngtcp2_crypto_cc *cc = ppe->cc;
|
||||
|
||||
if (ngtcp2_buf_left(buf) < cc->aead.max_overhead) {
|
||||
if (buf_left <= cc->aead.max_overhead) {
|
||||
return NGTCP2_ERR_NOBUF;
|
||||
}
|
||||
|
||||
rv = ngtcp2_pkt_encode_frame(
|
||||
buf->last, ngtcp2_buf_left(buf) - cc->aead.max_overhead, fr);
|
||||
rv = ngtcp2_pkt_encode_frame(buf->last, buf_left - cc->aead.max_overhead, fr);
|
||||
if (rv < 0) {
|
||||
return (int)rv;
|
||||
}
|
||||
|
@ -172,18 +173,13 @@ ngtcp2_ssize ngtcp2_ppe_final(ngtcp2_ppe *ppe, const uint8_t **ppkt) {
|
|||
|
||||
size_t ngtcp2_ppe_left(const ngtcp2_ppe *ppe) {
|
||||
ngtcp2_crypto_cc *cc = ppe->cc;
|
||||
size_t buf_left = ngtcp2_buf_left(&ppe->buf);
|
||||
|
||||
if (ngtcp2_buf_left(&ppe->buf) < cc->aead.max_overhead) {
|
||||
if (buf_left <= cc->aead.max_overhead) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ngtcp2_buf_left(&ppe->buf) - cc->aead.max_overhead;
|
||||
}
|
||||
|
||||
size_t ngtcp2_ppe_pktlen(const ngtcp2_ppe *ppe) {
|
||||
ngtcp2_crypto_cc *cc = ppe->cc;
|
||||
|
||||
return ngtcp2_buf_len(&ppe->buf) + cc->aead.max_overhead;
|
||||
return buf_left - cc->aead.max_overhead;
|
||||
}
|
||||
|
||||
size_t ngtcp2_ppe_padding_size(ngtcp2_ppe *ppe, size_t n) {
|
||||
|
@ -208,6 +204,10 @@ size_t ngtcp2_ppe_padding_size(ngtcp2_ppe *ppe, size_t n) {
|
|||
|
||||
assert(ngtcp2_buf_left(buf) >= len + cc->aead.max_overhead);
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf->last = ngtcp2_setmem(buf->last, 0, len);
|
||||
|
||||
return len;
|
||||
|
|
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.h
vendored
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.h
vendored
|
@ -110,12 +110,6 @@ ngtcp2_ssize ngtcp2_ppe_final(ngtcp2_ppe *ppe, const uint8_t **ppkt);
|
|||
*/
|
||||
size_t ngtcp2_ppe_left(const ngtcp2_ppe *ppe);
|
||||
|
||||
/*
|
||||
* ngtcp2_ppe_pktlen returns the provisional packet length. It
|
||||
* includes AEAD overhead.
|
||||
*/
|
||||
size_t ngtcp2_ppe_pktlen(const ngtcp2_ppe *ppe);
|
||||
|
||||
/*
|
||||
* ngtcp2_ppe_dgram_padding is equivalent to call
|
||||
* ngtcp2_ppe_dgram_padding_size(ppe, NGTCP2_MAX_UDP_PAYLOAD_SIZE).
|
||||
|
|
4
deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h
vendored
4
deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h
vendored
|
@ -110,7 +110,9 @@ void ngtcp2_ringbuf_resize(ngtcp2_ringbuf *rb, size_t len);
|
|||
void *ngtcp2_ringbuf_get(const ngtcp2_ringbuf *rb, size_t offset);
|
||||
|
||||
/* ngtcp2_ringbuf_len returns the number of elements stored. */
|
||||
#define ngtcp2_ringbuf_len(RB) ((RB)->len)
|
||||
static inline size_t ngtcp2_ringbuf_len(const ngtcp2_ringbuf *rb) {
|
||||
return rb->len;
|
||||
}
|
||||
|
||||
/* ngtcp2_ringbuf_full returns nonzero if |rb| is full. */
|
||||
int ngtcp2_ringbuf_full(const ngtcp2_ringbuf *rb);
|
||||
|
|
17
deps/ngtcp2/ngtcp2/lib/ngtcp2_rst.c
vendored
17
deps/ngtcp2/ngtcp2/lib/ngtcp2_rst.c
vendored
|
@ -38,7 +38,6 @@ void ngtcp2_rs_init(ngtcp2_rs *rs) {
|
|||
rs->prior_ts = UINT64_MAX;
|
||||
rs->tx_in_flight = 0;
|
||||
rs->lost = 0;
|
||||
rs->prior_lost = 0;
|
||||
rs->send_elapsed = 0;
|
||||
rs->ack_elapsed = 0;
|
||||
rs->last_end_seq = -1;
|
||||
|
@ -58,7 +57,6 @@ void ngtcp2_rst_reset(ngtcp2_rst *rst) {
|
|||
rst->app_limited = 0;
|
||||
rst->is_cwnd_limited = 0;
|
||||
rst->lost = 0;
|
||||
rst->valid_after_seq = rst->last_seq;
|
||||
}
|
||||
|
||||
void ngtcp2_rst_on_pkt_sent(ngtcp2_rst *rst, ngtcp2_rtb_entry *ent,
|
||||
|
@ -89,7 +87,6 @@ void ngtcp2_rst_on_ack_recv(ngtcp2_rst *rst, ngtcp2_conn_stat *cstat) {
|
|||
rs->interval = ngtcp2_max_uint64(rs->send_elapsed, rs->ack_elapsed);
|
||||
|
||||
rs->delivered = rst->delivered - rs->prior_delivered;
|
||||
rs->lost = rst->lost - rs->prior_lost;
|
||||
|
||||
if (rs->interval < cstat->min_rtt) {
|
||||
rs->interval = UINT64_MAX;
|
||||
|
@ -103,31 +100,23 @@ void ngtcp2_rst_on_ack_recv(ngtcp2_rst *rst, ngtcp2_conn_stat *cstat) {
|
|||
cstat->delivery_rate_sec = rs->delivered * NGTCP2_SECONDS / rs->interval;
|
||||
}
|
||||
|
||||
static int rst_is_newest_pkt(const ngtcp2_rst *rst, const ngtcp2_rtb_entry *ent,
|
||||
const ngtcp2_rs *rs) {
|
||||
return ent->ts > rst->first_sent_ts ||
|
||||
(ent->ts == rst->first_sent_ts && ent->rst.end_seq > rs->last_end_seq);
|
||||
static int is_newest_pkt(const ngtcp2_rtb_entry *ent, const ngtcp2_rs *rs) {
|
||||
return ent->rst.end_seq > rs->last_end_seq;
|
||||
}
|
||||
|
||||
void ngtcp2_rst_update_rate_sample(ngtcp2_rst *rst, const ngtcp2_rtb_entry *ent,
|
||||
ngtcp2_tstamp ts) {
|
||||
ngtcp2_rs *rs = &rst->rs;
|
||||
|
||||
if (ent->rst.end_seq <= rst->valid_after_seq) {
|
||||
return;
|
||||
}
|
||||
|
||||
rst->delivered += ent->pktlen;
|
||||
rst->delivered_ts = ts;
|
||||
|
||||
if (rs->prior_ts == UINT64_MAX || rst_is_newest_pkt(rst, ent, rs)) {
|
||||
if (rs->prior_ts == UINT64_MAX || is_newest_pkt(ent, rs)) {
|
||||
rs->prior_delivered = ent->rst.delivered;
|
||||
rs->prior_ts = ent->rst.delivered_ts;
|
||||
rs->is_app_limited = ent->rst.is_app_limited;
|
||||
rs->send_elapsed = ent->ts - ent->rst.first_sent_ts;
|
||||
rs->ack_elapsed = rst->delivered_ts - ent->rst.delivered_ts;
|
||||
rs->tx_in_flight = ent->rst.tx_in_flight;
|
||||
rs->prior_lost = ent->rst.lost;
|
||||
rs->last_end_seq = ent->rst.end_seq;
|
||||
rst->first_sent_ts = ent->ts;
|
||||
}
|
||||
|
|
5
deps/ngtcp2/ngtcp2/lib/ngtcp2_rst.h
vendored
5
deps/ngtcp2/ngtcp2/lib/ngtcp2_rst.h
vendored
|
@ -48,7 +48,6 @@ typedef struct ngtcp2_rs {
|
|||
ngtcp2_tstamp prior_ts;
|
||||
uint64_t tx_in_flight;
|
||||
uint64_t lost;
|
||||
uint64_t prior_lost;
|
||||
ngtcp2_duration send_elapsed;
|
||||
ngtcp2_duration ack_elapsed;
|
||||
int64_t last_end_seq;
|
||||
|
@ -73,10 +72,6 @@ typedef struct ngtcp2_rst {
|
|||
across all packet number spaces, we can replace this with a
|
||||
packet number. */
|
||||
int64_t last_seq;
|
||||
/* valid_after_seq is the sequence number, and ignore a packet if
|
||||
the sequence number of the packet is less than or equal to this
|
||||
number. */
|
||||
int64_t valid_after_seq;
|
||||
int is_cwnd_limited;
|
||||
} ngtcp2_rst;
|
||||
|
||||
|
|
201
deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c
vendored
201
deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c
vendored
|
@ -43,16 +43,19 @@ ngtcp2_objalloc_def(rtb_entry, ngtcp2_rtb_entry, oplent)
|
|||
static void rtb_entry_init(ngtcp2_rtb_entry *ent, const ngtcp2_pkt_hd *hd,
|
||||
ngtcp2_frame_chain *frc, ngtcp2_tstamp ts,
|
||||
size_t pktlen, uint16_t flags) {
|
||||
memset(ent, 0, sizeof(*ent));
|
||||
|
||||
ent->hd.pkt_num = hd->pkt_num;
|
||||
ent->hd.type = hd->type;
|
||||
ent->hd.flags = hd->flags;
|
||||
ent->frc = frc;
|
||||
ent->ts = ts;
|
||||
ent->lost_ts = UINT64_MAX;
|
||||
ent->pktlen = pktlen;
|
||||
ent->flags = flags;
|
||||
*ent = (ngtcp2_rtb_entry){
|
||||
.hd =
|
||||
{
|
||||
.pkt_num = hd->pkt_num,
|
||||
.type = hd->type,
|
||||
.flags = hd->flags,
|
||||
},
|
||||
.frc = frc,
|
||||
.ts = ts,
|
||||
.lost_ts = UINT64_MAX,
|
||||
.pktlen = pktlen,
|
||||
.flags = flags,
|
||||
};
|
||||
}
|
||||
|
||||
int ngtcp2_rtb_entry_objalloc_new(ngtcp2_rtb_entry **pent,
|
||||
|
@ -102,7 +105,7 @@ void ngtcp2_rtb_init(ngtcp2_rtb *rtb, ngtcp2_rst *rst, ngtcp2_cc *cc,
|
|||
rtb->cc_pkt_num = cc_pkt_num;
|
||||
rtb->cc_bytes_in_flight = 0;
|
||||
rtb->num_lost_pkts = 0;
|
||||
rtb->num_lost_pmtud_pkts = 0;
|
||||
rtb->num_lost_ignore_pkts = 0;
|
||||
}
|
||||
|
||||
void ngtcp2_rtb_free(ngtcp2_rtb *rtb) {
|
||||
|
@ -153,9 +156,10 @@ static size_t rtb_on_remove(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
|
|||
assert(rtb->num_lost_pkts);
|
||||
--rtb->num_lost_pkts;
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
|
||||
assert(rtb->num_lost_pmtud_pkts);
|
||||
--rtb->num_lost_pmtud_pkts;
|
||||
if (ent->flags &
|
||||
(NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE | NGTCP2_RTB_ENTRY_FLAG_SKIP)) {
|
||||
assert(rtb->num_lost_ignore_pkts);
|
||||
--rtb->num_lost_ignore_pkts;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -244,22 +248,17 @@ static ngtcp2_ssize rtb_reclaim_frame(ngtcp2_rtb *rtb, uint8_t flags,
|
|||
fr->stream.offset + ngtcp2_vec_len(fr->stream.data, fr->stream.datacnt);
|
||||
range = ngtcp2_range_intersect(&range, &gap);
|
||||
|
||||
if (ngtcp2_range_len(&range) == 0) {
|
||||
if (!fr->stream.fin) {
|
||||
if (ngtcp2_range_len(&range) == 0 && !fr->stream.fin &&
|
||||
/* 0 length STREAM frame with offset == 0 must be
|
||||
retransmitted if no non-empty data are sent to this
|
||||
stream, fin flag is not set, and no data in this stream
|
||||
are acknowledged. */
|
||||
if (fr->stream.offset != 0 || fr->stream.datacnt != 0 ||
|
||||
(fr->stream.offset != 0 || fr->stream.datacnt != 0 ||
|
||||
strm->tx.offset ||
|
||||
(strm->flags &
|
||||
(NGTCP2_STRM_FLAG_SHUT_WR | NGTCP2_STRM_FLAG_ANY_ACKED))) {
|
||||
(NGTCP2_STRM_FLAG_SHUT_WR | NGTCP2_STRM_FLAG_ANY_ACKED)))) {
|
||||
continue;
|
||||
}
|
||||
} else if (strm->flags & NGTCP2_STRM_FLAG_FIN_ACKED) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & NGTCP2_RECLAIM_FLAG_ON_LOSS) &&
|
||||
ent->hd.pkt_num != strm->tx.last_lost_pkt_num) {
|
||||
|
@ -443,16 +442,22 @@ static int rtb_on_pkt_lost(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
|
|||
ngtcp2_cc *cc = rtb->cc;
|
||||
ngtcp2_cc_pkt pkt;
|
||||
|
||||
if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_SKIP)) {
|
||||
ngtcp2_log_pkt_lost(rtb->log, ent->hd.pkt_num, ent->hd.type, ent->hd.flags,
|
||||
ent->ts);
|
||||
|
||||
if (rtb->qlog) {
|
||||
ngtcp2_qlog_pkt_lost(rtb->qlog, ent);
|
||||
}
|
||||
}
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
|
||||
++rtb->num_lost_pmtud_pkts;
|
||||
} else if (rtb->cc->on_pkt_lost) {
|
||||
if (ent->flags &
|
||||
(NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE | NGTCP2_RTB_ENTRY_FLAG_SKIP)) {
|
||||
++rtb->num_lost_ignore_pkts;
|
||||
} else if (ent->hd.pkt_num >= rtb->cc_pkt_num) {
|
||||
rtb->rst->lost += ent->pktlen;
|
||||
|
||||
if (rtb->cc->on_pkt_lost) {
|
||||
cc->on_pkt_lost(cc, cstat,
|
||||
ngtcp2_cc_pkt_init(&pkt, ent->hd.pkt_num, ent->pktlen,
|
||||
pktns->id, ent->ts, ent->rst.lost,
|
||||
|
@ -460,6 +465,7 @@ static int rtb_on_pkt_lost(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
|
|||
ent->rst.is_app_limited),
|
||||
ts);
|
||||
}
|
||||
}
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED) {
|
||||
ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
|
||||
|
@ -705,6 +711,8 @@ static void rtb_on_pkt_acked(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
|
|||
ngtcp2_cc *cc = rtb->cc;
|
||||
ngtcp2_cc_pkt pkt;
|
||||
|
||||
assert(ent->hd.pkt_num >= rtb->cc_pkt_num);
|
||||
|
||||
ngtcp2_rst_update_rate_sample(rtb->rst, ent, ts);
|
||||
|
||||
if (cc->on_pkt_acked) {
|
||||
|
@ -786,7 +794,7 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
|
|||
size_t ecn_acked = 0;
|
||||
int verify_ecn = 0;
|
||||
ngtcp2_cc_ack cc_ack = {0};
|
||||
size_t num_lost_pkts = rtb->num_lost_pkts - rtb->num_lost_pmtud_pkts;
|
||||
size_t num_lost_pkts = rtb->num_lost_pkts - rtb->num_lost_ignore_pkts;
|
||||
|
||||
cc_ack.prior_bytes_in_flight = cstat->bytes_in_flight;
|
||||
cc_ack.rtt = UINT64_MAX;
|
||||
|
@ -830,6 +838,11 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
|
|||
|
||||
ent = ngtcp2_ksl_it_get(&it);
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_SKIP) {
|
||||
rv = NGTCP2_ERR_PROTO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (largest_ack == pkt_num) {
|
||||
largest_pkt_sent_ts = ent->ts;
|
||||
}
|
||||
|
@ -839,7 +852,6 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
|
|||
}
|
||||
|
||||
rtb_remove(rtb, &it, &acked_ent, ent, cstat);
|
||||
++num_acked;
|
||||
}
|
||||
|
||||
for (i = 0; i < fr->rangecnt; ++i) {
|
||||
|
@ -859,12 +871,16 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
|
|||
|
||||
ent = ngtcp2_ksl_it_get(&it);
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_SKIP) {
|
||||
rv = NGTCP2_ERR_PROTO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
|
||||
ack_eliciting_pkt_acked = 1;
|
||||
}
|
||||
|
||||
rtb_remove(rtb, &it, &acked_ent, ent, cstat);
|
||||
++num_acked;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -873,7 +889,8 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
|
|||
ngtcp2_max_uint64(pkt_ts - largest_pkt_sent_ts, NGTCP2_NANOSECONDS);
|
||||
|
||||
rv = ngtcp2_conn_update_rtt(conn, cc_ack.rtt, fr->ack_delay_unscaled, ts);
|
||||
if (rv == 0 && cc->new_rtt_sample) {
|
||||
if (rv == 0 && cc->new_rtt_sample &&
|
||||
rtb->largest_acked_tx_pkt_num >= rtb->cc_pkt_num) {
|
||||
cc->new_rtt_sample(cc, cstat, ts);
|
||||
}
|
||||
}
|
||||
|
@ -895,9 +912,12 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
|
|||
|
||||
cc_ack.bytes_delivered += ent->pktlen;
|
||||
cc_ack.pkt_delivered = ent->rst.delivered;
|
||||
}
|
||||
|
||||
rtb_on_pkt_acked(rtb, ent, cstat, pktns, ts);
|
||||
|
||||
++num_acked;
|
||||
}
|
||||
|
||||
acked_ent = ent->next;
|
||||
ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
|
||||
rtb->frc_objalloc, rtb->mem);
|
||||
|
@ -912,13 +932,14 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
|
|||
for (ent = acked_ent; ent; ent = acked_ent) {
|
||||
rtb_on_pkt_acked(rtb, ent, cstat, pktns, ts);
|
||||
acked_ent = ent->next;
|
||||
++num_acked;
|
||||
ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
|
||||
rtb->frc_objalloc, rtb->mem);
|
||||
}
|
||||
}
|
||||
|
||||
if (rtb->cc->on_spurious_congestion && num_lost_pkts &&
|
||||
rtb->num_lost_pkts == rtb->num_lost_pmtud_pkts) {
|
||||
rtb->num_lost_pkts == rtb->num_lost_ignore_pkts) {
|
||||
rtb->cc->on_spurious_congestion(cc, cstat, ts);
|
||||
}
|
||||
|
||||
|
@ -933,8 +954,6 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
|
|||
}
|
||||
}
|
||||
|
||||
rtb->rst->lost += cc_ack.bytes_lost;
|
||||
|
||||
cc_ack.largest_pkt_sent_ts = largest_pkt_sent_ts;
|
||||
if (num_acked && cc->on_ack_recv) {
|
||||
cc->on_ack_recv(cc, cstat, &cc_ack, ts);
|
||||
|
@ -1189,8 +1208,9 @@ void ngtcp2_rtb_remove_excessive_lost_pkt(ngtcp2_rtb *rtb, size_t n) {
|
|||
|
||||
--rtb->num_lost_pkts;
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
|
||||
--rtb->num_lost_pmtud_pkts;
|
||||
if (ent->flags &
|
||||
(NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE | NGTCP2_RTB_ENTRY_FLAG_SKIP)) {
|
||||
--rtb->num_lost_ignore_pkts;
|
||||
}
|
||||
|
||||
rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
|
||||
|
@ -1200,27 +1220,28 @@ void ngtcp2_rtb_remove_excessive_lost_pkt(ngtcp2_rtb *rtb, size_t n) {
|
|||
}
|
||||
}
|
||||
|
||||
void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_duration pto,
|
||||
void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb,
|
||||
ngtcp2_duration timeout,
|
||||
ngtcp2_tstamp ts) {
|
||||
ngtcp2_ksl_it it;
|
||||
ngtcp2_rtb_entry *ent;
|
||||
int rv;
|
||||
(void)rv;
|
||||
|
||||
if (ngtcp2_ksl_len(&rtb->ents) == 0) {
|
||||
if (rtb->num_lost_pkts == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
it = ngtcp2_ksl_end(&rtb->ents);
|
||||
|
||||
for (;;) {
|
||||
for (; rtb->num_lost_pkts;) {
|
||||
assert(ngtcp2_ksl_it_end(&it));
|
||||
|
||||
ngtcp2_ksl_it_prev(&it);
|
||||
ent = ngtcp2_ksl_it_get(&it);
|
||||
|
||||
if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) ||
|
||||
ts - ent->lost_ts < pto) {
|
||||
ts - ent->lost_ts < timeout) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1229,18 +1250,15 @@ void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_duration pto,
|
|||
|
||||
--rtb->num_lost_pkts;
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
|
||||
--rtb->num_lost_pmtud_pkts;
|
||||
if (ent->flags &
|
||||
(NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE | NGTCP2_RTB_ENTRY_FLAG_SKIP)) {
|
||||
--rtb->num_lost_ignore_pkts;
|
||||
}
|
||||
|
||||
rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
|
||||
assert(0 == rv);
|
||||
ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
|
||||
rtb->frc_objalloc, rtb->mem);
|
||||
|
||||
if (ngtcp2_ksl_len(&rtb->ents) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1263,60 +1281,14 @@ ngtcp2_tstamp ngtcp2_rtb_lost_pkt_ts(const ngtcp2_rtb *rtb) {
|
|||
return ent->lost_ts;
|
||||
}
|
||||
|
||||
static int rtb_on_pkt_lost_resched_move(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
||||
static int rtb_reclaim_frame_on_retry(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
||||
ngtcp2_pktns *pktns,
|
||||
ngtcp2_rtb_entry *ent) {
|
||||
ngtcp2_frame_chain **pfrc, *frc;
|
||||
ngtcp2_frame_chain **pfrc = &ent->frc, *frc;
|
||||
ngtcp2_stream *sfr;
|
||||
ngtcp2_strm *strm;
|
||||
int rv;
|
||||
|
||||
ngtcp2_log_pkt_lost(rtb->log, ent->hd.pkt_num, ent->hd.type, ent->hd.flags,
|
||||
ent->ts);
|
||||
|
||||
if (rtb->qlog) {
|
||||
ngtcp2_qlog_pkt_lost(rtb->qlog, ent);
|
||||
}
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PROBE) {
|
||||
ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
|
||||
"pkn=%" PRId64
|
||||
" is a probe packet, no retransmission is necessary",
|
||||
ent->hd.pkt_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED) {
|
||||
--rtb->num_lost_pkts;
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) {
|
||||
--rtb->num_lost_pmtud_pkts;
|
||||
}
|
||||
|
||||
ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
|
||||
"pkn=%" PRId64
|
||||
" was declared lost and has already been retransmitted",
|
||||
ent->hd.pkt_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED) {
|
||||
ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
|
||||
"pkn=%" PRId64 " has already been reclaimed on PTO",
|
||||
ent->hd.pkt_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) &&
|
||||
(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_DATAGRAM) ||
|
||||
!conn->callbacks.lost_datagram)) {
|
||||
/* PADDING only (or PADDING + ACK ) packets will have NULL
|
||||
ent->frc. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
pfrc = &ent->frc;
|
||||
|
||||
for (; *pfrc;) {
|
||||
switch ((*pfrc)->fr.type) {
|
||||
case NGTCP2_FRAME_STREAM:
|
||||
|
@ -1390,14 +1362,12 @@ static int rtb_on_pkt_lost_resched_move(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ngtcp2_rtb_remove_all(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
||||
int ngtcp2_rtb_reclaim_on_retry(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
||||
ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat) {
|
||||
ngtcp2_rtb_entry *ent;
|
||||
ngtcp2_ksl_it it;
|
||||
ngtcp2_ksl_it it = ngtcp2_ksl_begin(&rtb->ents);
|
||||
int rv;
|
||||
|
||||
it = ngtcp2_ksl_begin(&rtb->ents);
|
||||
|
||||
for (; !ngtcp2_ksl_it_end(&it);) {
|
||||
ent = ngtcp2_ksl_it_get(&it);
|
||||
|
||||
|
@ -1405,7 +1375,42 @@ int ngtcp2_rtb_remove_all(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
|||
rv = ngtcp2_ksl_remove_hint(&rtb->ents, &it, &it, &ent->hd.pkt_num);
|
||||
assert(0 == rv);
|
||||
|
||||
rv = rtb_on_pkt_lost_resched_move(rtb, conn, pktns, ent);
|
||||
if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_SKIP)) {
|
||||
ngtcp2_log_pkt_lost(rtb->log, ent->hd.pkt_num, ent->hd.type,
|
||||
ent->hd.flags, ent->ts);
|
||||
|
||||
if (rtb->qlog) {
|
||||
ngtcp2_qlog_pkt_lost(rtb->qlog, ent);
|
||||
}
|
||||
}
|
||||
|
||||
/* We never send PING only probe packet because we should have
|
||||
CRYPTO data or just nothing. If we have nothing, then we do
|
||||
not send probe packet. */
|
||||
assert(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_PROBE));
|
||||
|
||||
/* We never get ACK before Retry packet. */
|
||||
assert(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED));
|
||||
assert(0 == rtb->num_lost_pkts);
|
||||
assert(0 == rtb->num_lost_ignore_pkts);
|
||||
|
||||
/* PMTUD probe must not be sent before handshake completion. */
|
||||
assert(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE));
|
||||
|
||||
if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED) {
|
||||
ngtcp2_log_info(rtb->log, NGTCP2_LOG_EVENT_LDC,
|
||||
"pkn=%" PRId64 " has already been reclaimed on PTO",
|
||||
ent->hd.pkt_num);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE) &&
|
||||
(!(ent->flags & NGTCP2_RTB_ENTRY_FLAG_DATAGRAM) ||
|
||||
!conn->callbacks.lost_datagram)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rv = rtb_reclaim_frame_on_retry(rtb, conn, pktns, ent);
|
||||
|
||||
ngtcp2_rtb_entry_objalloc_del(ent, rtb->rtb_entry_objalloc,
|
||||
rtb->frc_objalloc, rtb->mem);
|
||||
|
|
23
deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.h
vendored
23
deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.h
vendored
|
@ -80,6 +80,9 @@ typedef struct ngtcp2_frame_chain ngtcp2_frame_chain;
|
|||
/* NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING indicates that the entry
|
||||
includes a packet which elicits PTO probe packets. */
|
||||
#define NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING 0x100u
|
||||
/* NGTCP2_RTB_ENTRY_FLAG_SKIP indicates that the entry has the skipped
|
||||
packet number. */
|
||||
#define NGTCP2_RTB_ENTRY_FLAG_SKIP 0x200u
|
||||
|
||||
typedef struct ngtcp2_rtb_entry ngtcp2_rtb_entry;
|
||||
|
||||
|
@ -187,10 +190,11 @@ typedef struct ngtcp2_rtb {
|
|||
/* num_lost_pkts is the number entries in ents which has
|
||||
NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED flag set. */
|
||||
size_t num_lost_pkts;
|
||||
/* num_lost_pmtud_pkts is the number of entries in ents which have
|
||||
both NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED and
|
||||
NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE flags set. */
|
||||
size_t num_lost_pmtud_pkts;
|
||||
/* num_lost_ignore_pkts is the number of entries in ents which have
|
||||
NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED flag set, and should be
|
||||
excluded from lost byte count. If only those packets are lost,
|
||||
congestion event is not triggered. */
|
||||
size_t num_lost_ignore_pkts;
|
||||
} ngtcp2_rtb;
|
||||
|
||||
/*
|
||||
|
@ -258,7 +262,8 @@ int ngtcp2_rtb_detect_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
|||
/*
|
||||
* ngtcp2_rtb_remove_expired_lost_pkt removes expired lost packet.
|
||||
*/
|
||||
void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_duration pto,
|
||||
void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb,
|
||||
ngtcp2_duration timeout,
|
||||
ngtcp2_tstamp ts);
|
||||
|
||||
/*
|
||||
|
@ -269,11 +274,11 @@ void ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_duration pto,
|
|||
ngtcp2_tstamp ngtcp2_rtb_lost_pkt_ts(const ngtcp2_rtb *rtb);
|
||||
|
||||
/*
|
||||
* ngtcp2_rtb_remove_all removes all packets from |rtb|, and prepends
|
||||
* all frames to |*pfrc|. Even when this function fails, some frames
|
||||
* might be prepended to |*pfrc|, and the caller should handle them.
|
||||
* ngtcp2_rtb_reclaim_on_retry is called when Retry packet is
|
||||
* received. It removes all packets from |rtb|, and retransmittable
|
||||
* frames are reclaimed for retransmission.
|
||||
*/
|
||||
int ngtcp2_rtb_remove_all(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
||||
int ngtcp2_rtb_reclaim_on_retry(ngtcp2_rtb *rtb, ngtcp2_conn *conn,
|
||||
ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat);
|
||||
|
||||
/*
|
||||
|
|
28
deps/ngtcp2/ngtcp2/lib/ngtcp2_strm.c
vendored
28
deps/ngtcp2/ngtcp2/lib/ngtcp2_strm.c
vendored
|
@ -120,7 +120,7 @@ uint64_t ngtcp2_strm_rx_offset(const ngtcp2_strm *strm) {
|
|||
/* strm_rob_heavily_fragmented returns nonzero if the number of gaps
|
||||
in |rob| exceeds the limit. */
|
||||
static int strm_rob_heavily_fragmented(const ngtcp2_rob *rob) {
|
||||
return ngtcp2_ksl_len(&rob->gapksl) >= 5000;
|
||||
return ngtcp2_ksl_len(&rob->gapksl) >= 1000;
|
||||
}
|
||||
|
||||
int ngtcp2_strm_recv_reordering(ngtcp2_strm *strm, const uint8_t *data,
|
||||
|
@ -138,11 +138,16 @@ int ngtcp2_strm_recv_reordering(ngtcp2_strm *strm, const uint8_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
rv = ngtcp2_rob_push(strm->rx.rob, offset, data, datalen);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (strm_rob_heavily_fragmented(strm->rx.rob)) {
|
||||
return NGTCP2_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
return ngtcp2_rob_push(strm->rx.rob, offset, data, datalen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ngtcp2_strm_update_rx_offset(ngtcp2_strm *strm, uint64_t offset) {
|
||||
|
@ -196,6 +201,8 @@ int ngtcp2_strm_streamfrq_push(ngtcp2_strm *strm, ngtcp2_frame_chain *frc) {
|
|||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
} else if (ngtcp2_ksl_len(strm->tx.streamfrq) >= 1000) {
|
||||
return NGTCP2_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
return ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &frc->fr.stream.offset,
|
||||
|
@ -398,7 +405,11 @@ int ngtcp2_strm_streamfrq_pop(ngtcp2_strm *strm, ngtcp2_frame_chain **pfrc,
|
|||
datalen = ngtcp2_vec_len(fr->data, fr->datacnt);
|
||||
|
||||
/* datalen could be zero if 0 length STREAM has been sent */
|
||||
if (left == 0 && datalen) {
|
||||
/* We might see more data in the queue, then left < datalen could be
|
||||
true. We only see the first one for now. */
|
||||
if ((fr->type == NGTCP2_FRAME_STREAM &&
|
||||
(left < datalen && left < NGTCP2_MIN_STREAM_DATALEN)) ||
|
||||
(left == 0 && datalen)) {
|
||||
rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &fr->offset, frc);
|
||||
if (rv != 0) {
|
||||
assert(ngtcp2_err_is_fatal(rv));
|
||||
|
@ -737,7 +748,16 @@ int ngtcp2_strm_ack_data(ngtcp2_strm *strm, uint64_t offset, uint64_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
return ngtcp2_gaptr_push(strm->tx.acked_offset, offset, len);
|
||||
rv = ngtcp2_gaptr_push(strm->tx.acked_offset, offset, len);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (ngtcp2_ksl_len(&strm->tx.acked_offset->gap) >= 1000) {
|
||||
return NGTCP2_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ngtcp2_strm_set_app_error_code(ngtcp2_strm *strm,
|
||||
|
|
12
deps/ngtcp2/ngtcp2/lib/ngtcp2_transport_params.c
vendored
12
deps/ngtcp2/ngtcp2/lib/ngtcp2_transport_params.c
vendored
|
@ -523,12 +523,12 @@ int ngtcp2_transport_params_decode_versioned(int transport_params_version,
|
|||
}
|
||||
|
||||
/* Set default values */
|
||||
memset(params, 0, sizeof(*params));
|
||||
params->max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE;
|
||||
params->ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
|
||||
params->max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
|
||||
params->active_connection_id_limit =
|
||||
NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
|
||||
*params = (ngtcp2_transport_params){
|
||||
.max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE,
|
||||
.ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT,
|
||||
.max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY,
|
||||
.active_connection_id_limit = NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT,
|
||||
};
|
||||
|
||||
p = end = data;
|
||||
|
||||
|
|
7
deps/ngtcp2/ngtcp2/lib/ngtcp2_vec.h
vendored
7
deps/ngtcp2/ngtcp2/lib/ngtcp2_vec.h
vendored
|
@ -33,13 +33,6 @@
|
|||
|
||||
#include "ngtcp2_mem.h"
|
||||
|
||||
/*
|
||||
* ngtcp2_vec_lit is a convenient macro to fill the object pointed by
|
||||
* |DEST| with the literal string |LIT|.
|
||||
*/
|
||||
#define ngtcp2_vec_lit(DEST, LIT) \
|
||||
((DEST)->base = (uint8_t *)(LIT), (DEST)->len = sizeof(LIT) - 1, (DEST))
|
||||
|
||||
/*
|
||||
* ngtcp2_vec_init initializes |vec| with the given parameters. It
|
||||
* returns |vec|.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// QUIC is only available in Openssl 3.5.x and later. It was not introduced in
|
||||
// Node.js until 3.5.1... prior to that we will not compile any of the QUIC
|
||||
// related code.
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30500010
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30500010 || OPENSSL_IS_BORINGSSL
|
||||
#define OPENSSL_NO_QUIC = 1
|
||||
#endif
|
||||
#else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue