mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
deps: update ngtcp2 to 1.11.0
PR-URL: https://github.com/nodejs/node/pull/57179 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
This commit is contained in:
parent
9a97b722aa
commit
9e103b09a4
|
|
@ -331,7 +331,7 @@ ngtcp2_crypto_hp_mask_cb(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
|
||||||
* :enum:`ngtcp2_encryption_level.NGTCP2_ENCRYPTION_LEVEL_0RTT`) to
|
* :enum:`ngtcp2_encryption_level.NGTCP2_ENCRYPTION_LEVEL_0RTT`) to
|
||||||
* set negotiated AEAD and message digest algorithm. After the
|
* set negotiated AEAD and message digest algorithm. After the
|
||||||
* successful call of this function, application can use
|
* successful call of this function, application can use
|
||||||
* `ngtcp2_conn_get_crypto_ctx` (or `ngtcp2_conn_get_early_crypto_ctx`
|
* `ngtcp2_conn_get_crypto_ctx` (or `ngtcp2_conn_get_0rtt_crypto_ctx`
|
||||||
* if |level| ==
|
* if |level| ==
|
||||||
* :enum:`ngtcp2_encryption_level.NGTCP2_ENCRYPTION_LEVEL_0RTT`) to
|
* :enum:`ngtcp2_encryption_level.NGTCP2_ENCRYPTION_LEVEL_0RTT`) to
|
||||||
* get :type:`ngtcp2_crypto_ctx`.
|
* get :type:`ngtcp2_crypto_ctx`.
|
||||||
|
|
@ -378,7 +378,7 @@ NGTCP2_EXTERN int ngtcp2_crypto_derive_and_install_rx_key(
|
||||||
* :enum:`ngtcp2_encryption_level.NGTCP2_ENCRYPTION_LEVEL_0RTT`) to
|
* :enum:`ngtcp2_encryption_level.NGTCP2_ENCRYPTION_LEVEL_0RTT`) to
|
||||||
* set negotiated AEAD and message digest algorithm. After the
|
* set negotiated AEAD and message digest algorithm. After the
|
||||||
* successful call of this function, application can use
|
* successful call of this function, application can use
|
||||||
* `ngtcp2_conn_get_crypto_ctx` (or `ngtcp2_conn_get_early_crypto_ctx`
|
* `ngtcp2_conn_get_crypto_ctx` (or `ngtcp2_conn_get_0rtt_crypto_ctx`
|
||||||
* if |level| ==
|
* if |level| ==
|
||||||
* :enum:`ngtcp2_encryption_level.NGTCP2_ENCRYPTION_LEVEL_0RTT`) to
|
* :enum:`ngtcp2_encryption_level.NGTCP2_ENCRYPTION_LEVEL_0RTT`) to
|
||||||
* get :type:`ngtcp2_crypto_ctx`.
|
* get :type:`ngtcp2_crypto_ctx`.
|
||||||
|
|
|
||||||
47
deps/ngtcp2/ngtcp2/crypto/picotls/picotls.c
vendored
47
deps/ngtcp2/ngtcp2/crypto/picotls/picotls.c
vendored
|
|
@ -125,7 +125,7 @@ static int supported_cipher_suite(ptls_cipher_suite_t *cs) {
|
||||||
#ifdef PTLS_OPENSSL_HAVE_CHACHA20_POLY1305
|
#ifdef PTLS_OPENSSL_HAVE_CHACHA20_POLY1305
|
||||||
|| cs->aead == &ptls_openssl_chacha20poly1305
|
|| cs->aead == &ptls_openssl_chacha20poly1305
|
||||||
#endif /* defined(PTLS_OPENSSL_HAVE_CHACHA20_POLY1305) */
|
#endif /* defined(PTLS_OPENSSL_HAVE_CHACHA20_POLY1305) */
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
|
ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
|
||||||
|
|
@ -146,7 +146,7 @@ ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
|
||||||
ctx->hp.native_handle = (void *)crypto_cipher_suite_get_hp(cs);
|
ctx->hp.native_handle = (void *)crypto_cipher_suite_get_hp(cs);
|
||||||
ctx->max_encryption = crypto_cipher_suite_get_aead_max_encryption(cs);
|
ctx->max_encryption = crypto_cipher_suite_get_aead_max_encryption(cs);
|
||||||
ctx->max_decryption_failure =
|
ctx->max_decryption_failure =
|
||||||
crypto_cipher_suite_get_aead_max_decryption_failure(cs);
|
crypto_cipher_suite_get_aead_max_decryption_failure(cs);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,19 +329,22 @@ int ngtcp2_crypto_decrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
|
||||||
const uint8_t *nonce, size_t noncelen,
|
const uint8_t *nonce, size_t noncelen,
|
||||||
const uint8_t *aad, size_t aadlen) {
|
const uint8_t *aad, size_t aadlen) {
|
||||||
ptls_aead_context_t *actx = aead_ctx->native_handle;
|
ptls_aead_context_t *actx = aead_ctx->native_handle;
|
||||||
|
size_t nwrite;
|
||||||
|
|
||||||
(void)aead;
|
(void)aead;
|
||||||
|
|
||||||
ptls_aead_xor_iv(actx, nonce, noncelen);
|
ptls_aead_xor_iv(actx, nonce, noncelen);
|
||||||
|
|
||||||
if (ptls_aead_decrypt(actx, dest, ciphertext, ciphertextlen, 0, aad,
|
nwrite =
|
||||||
aadlen) == SIZE_MAX) {
|
ptls_aead_decrypt(actx, dest, ciphertext, ciphertextlen, 0, aad, aadlen);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* zero-out static iv once again */
|
/* zero-out static iv once again */
|
||||||
ptls_aead_xor_iv(actx, nonce, noncelen);
|
ptls_aead_xor_iv(actx, nonce, noncelen);
|
||||||
|
|
||||||
|
if (nwrite == SIZE_MAX) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -360,13 +363,13 @@ int ngtcp2_crypto_hp_mask(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_crypto_read_write_crypto_data(
|
int ngtcp2_crypto_read_write_crypto_data(
|
||||||
ngtcp2_conn *conn, ngtcp2_encryption_level encryption_level,
|
ngtcp2_conn *conn, ngtcp2_encryption_level encryption_level,
|
||||||
const uint8_t *data, size_t datalen) {
|
const uint8_t *data, size_t datalen) {
|
||||||
ngtcp2_crypto_picotls_ctx *cptls = ngtcp2_conn_get_tls_native_handle(conn);
|
ngtcp2_crypto_picotls_ctx *cptls = ngtcp2_conn_get_tls_native_handle(conn);
|
||||||
ptls_buffer_t sendbuf;
|
ptls_buffer_t sendbuf;
|
||||||
size_t epoch_offsets[5] = {0};
|
size_t epoch_offsets[5] = {0};
|
||||||
size_t epoch =
|
size_t epoch =
|
||||||
ngtcp2_crypto_picotls_from_ngtcp2_encryption_level(encryption_level);
|
ngtcp2_crypto_picotls_from_ngtcp2_encryption_level(encryption_level);
|
||||||
size_t epoch_datalen;
|
size_t epoch_datalen;
|
||||||
size_t i;
|
size_t i;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -388,7 +391,7 @@ int ngtcp2_crypto_read_write_crypto_data(
|
||||||
|
|
||||||
if (!ngtcp2_conn_is_server(conn) &&
|
if (!ngtcp2_conn_is_server(conn) &&
|
||||||
cptls->handshake_properties.client.early_data_acceptance ==
|
cptls->handshake_properties.client.early_data_acceptance ==
|
||||||
PTLS_EARLY_DATA_REJECTED) {
|
PTLS_EARLY_DATA_REJECTED) {
|
||||||
rv = ngtcp2_conn_tls_early_data_rejected(conn);
|
rv = ngtcp2_conn_tls_early_data_rejected(conn);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
rv = -1;
|
rv = -1;
|
||||||
|
|
@ -405,8 +408,8 @@ int ngtcp2_crypto_read_write_crypto_data(
|
||||||
assert(i != 1);
|
assert(i != 1);
|
||||||
|
|
||||||
if (ngtcp2_conn_submit_crypto_data(
|
if (ngtcp2_conn_submit_crypto_data(
|
||||||
conn, ngtcp2_crypto_picotls_from_epoch(i),
|
conn, ngtcp2_crypto_picotls_from_epoch(i),
|
||||||
sendbuf.base + epoch_offsets[i], epoch_datalen) != 0) {
|
sendbuf.base + epoch_offsets[i], epoch_datalen) != 0) {
|
||||||
rv = -1;
|
rv = -1;
|
||||||
goto fin;
|
goto fin;
|
||||||
}
|
}
|
||||||
|
|
@ -463,7 +466,7 @@ ngtcp2_encryption_level ngtcp2_crypto_picotls_from_epoch(size_t epoch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ngtcp2_crypto_picotls_from_ngtcp2_encryption_level(
|
size_t ngtcp2_crypto_picotls_from_ngtcp2_encryption_level(
|
||||||
ngtcp2_encryption_level encryption_level) {
|
ngtcp2_encryption_level encryption_level) {
|
||||||
switch (encryption_level) {
|
switch (encryption_level) {
|
||||||
case NGTCP2_ENCRYPTION_LEVEL_INITIAL:
|
case NGTCP2_ENCRYPTION_LEVEL_INITIAL:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -532,8 +535,8 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_crypto_picotls_collect_extension(
|
int ngtcp2_crypto_picotls_collect_extension(
|
||||||
ptls_t *ptls, struct st_ptls_handshake_properties_t *properties,
|
ptls_t *ptls, struct st_ptls_handshake_properties_t *properties,
|
||||||
uint16_t type) {
|
uint16_t type) {
|
||||||
(void)ptls;
|
(void)ptls;
|
||||||
(void)properties;
|
(void)properties;
|
||||||
|
|
||||||
|
|
@ -541,8 +544,8 @@ int ngtcp2_crypto_picotls_collect_extension(
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_crypto_picotls_collected_extensions(
|
int ngtcp2_crypto_picotls_collected_extensions(
|
||||||
ptls_t *ptls, struct st_ptls_handshake_properties_t *properties,
|
ptls_t *ptls, struct st_ptls_handshake_properties_t *properties,
|
||||||
ptls_raw_extension_t *extensions) {
|
ptls_raw_extension_t *extensions) {
|
||||||
ngtcp2_crypto_conn_ref *conn_ref;
|
ngtcp2_crypto_conn_ref *conn_ref;
|
||||||
ngtcp2_conn *conn;
|
ngtcp2_conn *conn;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -558,7 +561,7 @@ int ngtcp2_crypto_picotls_collected_extensions(
|
||||||
conn = conn_ref->get_conn(conn_ref);
|
conn = conn_ref->get_conn(conn_ref);
|
||||||
|
|
||||||
rv = ngtcp2_conn_decode_and_set_remote_transport_params(
|
rv = ngtcp2_conn_decode_and_set_remote_transport_params(
|
||||||
conn, extensions->data.base, extensions->data.len);
|
conn, extensions->data.base, extensions->data.len);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
ngtcp2_conn_set_tls_error(conn, rv);
|
ngtcp2_conn_set_tls_error(conn, rv);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -613,7 +616,7 @@ static int update_traffic_key_server_cb(ptls_update_traffic_key_t *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ptls_update_traffic_key_t update_traffic_key_server = {
|
static ptls_update_traffic_key_t update_traffic_key_server = {
|
||||||
update_traffic_key_server_cb,
|
update_traffic_key_server_cb,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int update_traffic_key_cb(ptls_update_traffic_key_t *self, ptls_t *ptls,
|
static int update_traffic_key_cb(ptls_update_traffic_key_t *self, ptls_t *ptls,
|
||||||
|
|
@ -661,7 +664,7 @@ int ngtcp2_crypto_picotls_configure_client_context(ptls_context_t *ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_crypto_picotls_configure_server_session(
|
int ngtcp2_crypto_picotls_configure_server_session(
|
||||||
ngtcp2_crypto_picotls_ctx *cptls) {
|
ngtcp2_crypto_picotls_ctx *cptls) {
|
||||||
ptls_handshake_properties_t *hsprops = &cptls->handshake_properties;
|
ptls_handshake_properties_t *hsprops = &cptls->handshake_properties;
|
||||||
|
|
||||||
hsprops->collect_extension = ngtcp2_crypto_picotls_collect_extension;
|
hsprops->collect_extension = ngtcp2_crypto_picotls_collect_extension;
|
||||||
|
|
@ -671,7 +674,7 @@ int ngtcp2_crypto_picotls_configure_server_session(
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_crypto_picotls_configure_client_session(
|
int ngtcp2_crypto_picotls_configure_client_session(
|
||||||
ngtcp2_crypto_picotls_ctx *cptls, ngtcp2_conn *conn) {
|
ngtcp2_crypto_picotls_ctx *cptls, ngtcp2_conn *conn) {
|
||||||
ptls_handshake_properties_t *hsprops = &cptls->handshake_properties;
|
ptls_handshake_properties_t *hsprops = &cptls->handshake_properties;
|
||||||
|
|
||||||
hsprops->client.max_early_data_size = calloc(1, sizeof(size_t));
|
hsprops->client.max_early_data_size = calloc(1, sizeof(size_t));
|
||||||
|
|
@ -692,7 +695,7 @@ int ngtcp2_crypto_picotls_configure_client_session(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ngtcp2_crypto_picotls_deconfigure_session(
|
void ngtcp2_crypto_picotls_deconfigure_session(
|
||||||
ngtcp2_crypto_picotls_ctx *cptls) {
|
ngtcp2_crypto_picotls_ctx *cptls) {
|
||||||
ptls_handshake_properties_t *hsprops;
|
ptls_handshake_properties_t *hsprops;
|
||||||
ptls_raw_extension_t *exts;
|
ptls_raw_extension_t *exts;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,8 +167,12 @@ typedef void *(*ngtcp2_realloc)(void *ptr, size_t size, void *user_data);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* void conn_new() {
|
* void conn_new() {
|
||||||
* ngtcp2_mem mem = {NULL, my_malloc_cb, my_free_cb, my_calloc_cb,
|
* ngtcp2_mem mem = {
|
||||||
* my_realloc_cb};
|
* .malloc = my_malloc_cb,
|
||||||
|
* .free = my_free_cb,
|
||||||
|
* .calloc = my_calloc_cb,
|
||||||
|
* .realloc = my_realloc_cb,
|
||||||
|
* };
|
||||||
*
|
*
|
||||||
* ...
|
* ...
|
||||||
* }
|
* }
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
*
|
*
|
||||||
* Version number of the ngtcp2 library release.
|
* Version number of the ngtcp2 library release.
|
||||||
*/
|
*/
|
||||||
#define NGTCP2_VERSION "1.10.0"
|
#define NGTCP2_VERSION "1.11.0"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @macro
|
* @macro
|
||||||
|
|
@ -46,6 +46,6 @@
|
||||||
* number, 8 bits for minor and 8 bits for patch. Version 1.2.3
|
* number, 8 bits for minor and 8 bits for patch. Version 1.2.3
|
||||||
* becomes 0x010203.
|
* becomes 0x010203.
|
||||||
*/
|
*/
|
||||||
#define NGTCP2_VERSION_NUM 0x010a00
|
#define NGTCP2_VERSION_NUM 0x010b00
|
||||||
|
|
||||||
#endif /* !defined(NGTCP2_VERSION_H) */
|
#endif /* !defined(NGTCP2_VERSION_H) */
|
||||||
|
|
|
||||||
114
deps/ngtcp2/ngtcp2/lib/ngtcp2_acktr.c
vendored
114
deps/ngtcp2/ngtcp2/lib/ngtcp2_acktr.c
vendored
|
|
@ -25,6 +25,7 @@
|
||||||
#include "ngtcp2_acktr.h"
|
#include "ngtcp2_acktr.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "ngtcp2_macro.h"
|
#include "ngtcp2_macro.h"
|
||||||
#include "ngtcp2_tstamp.h"
|
#include "ngtcp2_tstamp.h"
|
||||||
|
|
@ -70,6 +71,9 @@ void ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log,
|
||||||
acktr->flags = NGTCP2_ACKTR_FLAG_NONE;
|
acktr->flags = NGTCP2_ACKTR_FLAG_NONE;
|
||||||
acktr->first_unacked_ts = UINT64_MAX;
|
acktr->first_unacked_ts = UINT64_MAX;
|
||||||
acktr->rx_npkt = 0;
|
acktr->rx_npkt = 0;
|
||||||
|
acktr->max_pkt_num = -1;
|
||||||
|
acktr->max_pkt_ts = UINT64_MAX;
|
||||||
|
memset(&acktr->ecn, 0, sizeof(acktr->ecn));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ngtcp2_acktr_free(ngtcp2_acktr *acktr) {
|
void ngtcp2_acktr_free(ngtcp2_acktr *acktr) {
|
||||||
|
|
@ -180,6 +184,11 @@ int ngtcp2_acktr_add(ngtcp2_acktr *acktr, int64_t pkt_num, int active_ack,
|
||||||
ngtcp2_acktr_entry_objalloc_del(delent, &acktr->objalloc);
|
ngtcp2_acktr_entry_objalloc_del(delent, &acktr->objalloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (acktr->max_pkt_num < pkt_num) {
|
||||||
|
acktr->max_pkt_num = pkt_num;
|
||||||
|
acktr->max_pkt_ts = ts;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,3 +332,108 @@ int ngtcp2_acktr_require_active_ack(const ngtcp2_acktr *acktr,
|
||||||
void ngtcp2_acktr_immediate_ack(ngtcp2_acktr *acktr) {
|
void ngtcp2_acktr_immediate_ack(ngtcp2_acktr *acktr) {
|
||||||
acktr->flags |= NGTCP2_ACKTR_FLAG_IMMEDIATE_ACK;
|
acktr->flags |= NGTCP2_ACKTR_FLAG_IMMEDIATE_ACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngtcp2_frame *ngtcp2_acktr_create_ack_frame(ngtcp2_acktr *acktr,
|
||||||
|
ngtcp2_frame *fr, uint8_t type,
|
||||||
|
ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_duration ack_delay,
|
||||||
|
uint64_t ack_delay_exponent) {
|
||||||
|
int64_t last_pkt_num;
|
||||||
|
ngtcp2_ack_range *range;
|
||||||
|
ngtcp2_ksl_it it;
|
||||||
|
ngtcp2_acktr_entry *rpkt;
|
||||||
|
ngtcp2_ack *ack = &fr->ack;
|
||||||
|
ngtcp2_tstamp largest_ack_ts;
|
||||||
|
size_t num_acks;
|
||||||
|
|
||||||
|
if (acktr->flags & NGTCP2_ACKTR_FLAG_IMMEDIATE_ACK) {
|
||||||
|
ack_delay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ngtcp2_acktr_require_active_ack(acktr, ack_delay, ts)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
it = ngtcp2_acktr_get(acktr);
|
||||||
|
if (ngtcp2_ksl_it_end(&it)) {
|
||||||
|
ngtcp2_acktr_commit_ack(acktr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_acks = ngtcp2_ksl_len(&acktr->ents);
|
||||||
|
|
||||||
|
if (acktr->ecn.ect0 || acktr->ecn.ect1 || acktr->ecn.ce) {
|
||||||
|
ack->type = NGTCP2_FRAME_ACK_ECN;
|
||||||
|
ack->ecn.ect0 = acktr->ecn.ect0;
|
||||||
|
ack->ecn.ect1 = acktr->ecn.ect1;
|
||||||
|
ack->ecn.ce = acktr->ecn.ce;
|
||||||
|
} else {
|
||||||
|
ack->type = NGTCP2_FRAME_ACK;
|
||||||
|
}
|
||||||
|
ack->rangecnt = 0;
|
||||||
|
|
||||||
|
rpkt = ngtcp2_ksl_it_get(&it);
|
||||||
|
|
||||||
|
if (rpkt->pkt_num == acktr->max_pkt_num) {
|
||||||
|
last_pkt_num = rpkt->pkt_num - (int64_t)(rpkt->len - 1);
|
||||||
|
largest_ack_ts = rpkt->tstamp;
|
||||||
|
ack->largest_ack = rpkt->pkt_num;
|
||||||
|
ack->first_ack_range = rpkt->len - 1;
|
||||||
|
|
||||||
|
ngtcp2_ksl_it_next(&it);
|
||||||
|
--num_acks;
|
||||||
|
} else if (rpkt->pkt_num + 1 == acktr->max_pkt_num) {
|
||||||
|
last_pkt_num = rpkt->pkt_num - (int64_t)(rpkt->len - 1);
|
||||||
|
largest_ack_ts = acktr->max_pkt_ts;
|
||||||
|
ack->largest_ack = acktr->max_pkt_num;
|
||||||
|
ack->first_ack_range = rpkt->len;
|
||||||
|
|
||||||
|
ngtcp2_ksl_it_next(&it);
|
||||||
|
--num_acks;
|
||||||
|
} else {
|
||||||
|
assert(rpkt->pkt_num < acktr->max_pkt_num);
|
||||||
|
|
||||||
|
last_pkt_num = acktr->max_pkt_num;
|
||||||
|
largest_ack_ts = acktr->max_pkt_ts;
|
||||||
|
ack->largest_ack = acktr->max_pkt_num;
|
||||||
|
ack->first_ack_range = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == NGTCP2_PKT_1RTT) {
|
||||||
|
ack->ack_delay_unscaled = ts - largest_ack_ts;
|
||||||
|
ack->ack_delay = ack->ack_delay_unscaled / NGTCP2_MICROSECONDS /
|
||||||
|
(1ULL << ack_delay_exponent);
|
||||||
|
} else {
|
||||||
|
ack->ack_delay_unscaled = 0;
|
||||||
|
ack->ack_delay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_acks = ngtcp2_min_size(num_acks, NGTCP2_MAX_ACK_RANGES);
|
||||||
|
|
||||||
|
for (; ack->rangecnt < num_acks; ngtcp2_ksl_it_next(&it)) {
|
||||||
|
rpkt = ngtcp2_ksl_it_get(&it);
|
||||||
|
|
||||||
|
range = &ack->ranges[ack->rangecnt++];
|
||||||
|
range->gap = (uint64_t)(last_pkt_num - rpkt->pkt_num - 2);
|
||||||
|
range->len = rpkt->len - 1;
|
||||||
|
|
||||||
|
last_pkt_num = rpkt->pkt_num - (int64_t)(rpkt->len - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngtcp2_acktr_increase_ecn_counts(ngtcp2_acktr *acktr,
|
||||||
|
const ngtcp2_pkt_info *pi) {
|
||||||
|
switch (pi->ecn & NGTCP2_ECN_MASK) {
|
||||||
|
case NGTCP2_ECN_ECT_0:
|
||||||
|
++acktr->ecn.ect0;
|
||||||
|
break;
|
||||||
|
case NGTCP2_ECN_ECT_1:
|
||||||
|
++acktr->ecn.ect1;
|
||||||
|
break;
|
||||||
|
case NGTCP2_ECN_CE:
|
||||||
|
++acktr->ecn.ce;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
44
deps/ngtcp2/ngtcp2/lib/ngtcp2_acktr.h
vendored
44
deps/ngtcp2/ngtcp2/lib/ngtcp2_acktr.h
vendored
|
|
@ -128,6 +128,26 @@ typedef struct ngtcp2_acktr {
|
||||||
/* rx_npkt is the number of ACK eliciting packets received without
|
/* rx_npkt is the number of ACK eliciting packets received without
|
||||||
sending ACK. */
|
sending ACK. */
|
||||||
size_t rx_npkt;
|
size_t rx_npkt;
|
||||||
|
/* max_pkt_num is the largest packet number received so far. */
|
||||||
|
int64_t max_pkt_num;
|
||||||
|
/* max_pkt_ts is the timestamp when max_pkt_num packet is
|
||||||
|
received. */
|
||||||
|
ngtcp2_tstamp max_pkt_ts;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
/* ect0, ect1, and ce are the number of QUIC packets received
|
||||||
|
with those markings. */
|
||||||
|
size_t ect0;
|
||||||
|
size_t ect1;
|
||||||
|
size_t ce;
|
||||||
|
struct {
|
||||||
|
/* ect0, ect1, ce are the ECN counts received in the latest
|
||||||
|
ACK frame. */
|
||||||
|
uint64_t ect0;
|
||||||
|
uint64_t ect1;
|
||||||
|
uint64_t ce;
|
||||||
|
} ack;
|
||||||
|
} ecn;
|
||||||
} ngtcp2_acktr;
|
} ngtcp2_acktr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -165,7 +185,7 @@ int ngtcp2_acktr_add(ngtcp2_acktr *acktr, int64_t pkt_num, int active_ack,
|
||||||
void ngtcp2_acktr_forget(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent);
|
void ngtcp2_acktr_forget(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_acktr_get returns the pointer to pointer to the entry which
|
* ngtcp2_acktr_get returns the iterator to pointer to the entry which
|
||||||
* has the largest packet number to be acked. If there is no entry,
|
* has the largest packet number to be acked. If there is no entry,
|
||||||
* returned value satisfies ngtcp2_ksl_it_end(&it) != 0.
|
* returned value satisfies ngtcp2_ksl_it_end(&it) != 0.
|
||||||
*/
|
*/
|
||||||
|
|
@ -213,4 +233,26 @@ int ngtcp2_acktr_require_active_ack(const ngtcp2_acktr *acktr,
|
||||||
*/
|
*/
|
||||||
void ngtcp2_acktr_immediate_ack(ngtcp2_acktr *acktr);
|
void ngtcp2_acktr_immediate_ack(ngtcp2_acktr *acktr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_acktr_create_ack_frame creates ACK frame in the object
|
||||||
|
* pointed by |fr|, and returns |fr| if there are any received packets
|
||||||
|
* to acknowledge. If there are no packets to acknowledge, this
|
||||||
|
* function returns NULL. fr->ack.ranges must be able to contain at
|
||||||
|
* least NGTCP2_MAX_ACK_RANGES elements.
|
||||||
|
*
|
||||||
|
* Call ngtcp2_acktr_commit_ack after a created ACK frame is
|
||||||
|
* successfully serialized into a packet.
|
||||||
|
*/
|
||||||
|
ngtcp2_frame *ngtcp2_acktr_create_ack_frame(ngtcp2_acktr *acktr,
|
||||||
|
ngtcp2_frame *fr, uint8_t type,
|
||||||
|
ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_duration ack_delay,
|
||||||
|
uint64_t ack_delay_exponent);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_acktr_increase_ecn_counts increases ECN counts from |pi|.
|
||||||
|
*/
|
||||||
|
void ngtcp2_acktr_increase_ecn_counts(ngtcp2_acktr *acktr,
|
||||||
|
const ngtcp2_pkt_info *pi);
|
||||||
|
|
||||||
#endif /* !defined(NGTCP2_ACKTR_H) */
|
#endif /* !defined(NGTCP2_ACKTR_H) */
|
||||||
|
|
|
||||||
23
deps/ngtcp2/ngtcp2/lib/ngtcp2_addr.c
vendored
23
deps/ngtcp2/ngtcp2/lib/ngtcp2_addr.c
vendored
|
|
@ -51,8 +51,10 @@ void ngtcp2_addr_copy_byte(ngtcp2_addr *dest, const ngtcp2_sockaddr *addr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sockaddr_eq(const ngtcp2_sockaddr *a, const ngtcp2_sockaddr *b) {
|
int ngtcp2_sockaddr_eq(const ngtcp2_sockaddr *a, const ngtcp2_sockaddr *b) {
|
||||||
assert(a->sa_family == b->sa_family);
|
if (a->sa_family != b->sa_family) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (a->sa_family) {
|
switch (a->sa_family) {
|
||||||
case NGTCP2_AF_INET: {
|
case NGTCP2_AF_INET: {
|
||||||
|
|
@ -73,17 +75,16 @@ static int sockaddr_eq(const ngtcp2_sockaddr *a, const ngtcp2_sockaddr *b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_addr_eq(const ngtcp2_addr *a, const ngtcp2_addr *b) {
|
int ngtcp2_addr_eq(const ngtcp2_addr *a, const ngtcp2_addr *b) {
|
||||||
return a->addr->sa_family == b->addr->sa_family &&
|
return ngtcp2_sockaddr_eq(a->addr, b->addr);
|
||||||
sockaddr_eq(a->addr, b->addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ngtcp2_addr_compare(const ngtcp2_addr *aa, const ngtcp2_addr *bb) {
|
uint32_t ngtcp2_addr_cmp(const ngtcp2_addr *aa, const ngtcp2_addr *bb) {
|
||||||
uint32_t flags = NGTCP2_ADDR_COMPARE_FLAG_NONE;
|
uint32_t flags = NGTCP2_ADDR_CMP_FLAG_NONE;
|
||||||
const ngtcp2_sockaddr *a = aa->addr;
|
const ngtcp2_sockaddr *a = aa->addr;
|
||||||
const ngtcp2_sockaddr *b = bb->addr;
|
const ngtcp2_sockaddr *b = bb->addr;
|
||||||
|
|
||||||
if (a->sa_family != b->sa_family) {
|
if (a->sa_family != b->sa_family) {
|
||||||
return NGTCP2_ADDR_COMPARE_FLAG_FAMILY;
|
return NGTCP2_ADDR_CMP_FLAG_FAMILY;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (a->sa_family) {
|
switch (a->sa_family) {
|
||||||
|
|
@ -91,10 +92,10 @@ uint32_t ngtcp2_addr_compare(const ngtcp2_addr *aa, const ngtcp2_addr *bb) {
|
||||||
const ngtcp2_sockaddr_in *ai = (const ngtcp2_sockaddr_in *)(void *)a,
|
const ngtcp2_sockaddr_in *ai = (const ngtcp2_sockaddr_in *)(void *)a,
|
||||||
*bi = (const ngtcp2_sockaddr_in *)(void *)b;
|
*bi = (const ngtcp2_sockaddr_in *)(void *)b;
|
||||||
if (memcmp(&ai->sin_addr, &bi->sin_addr, sizeof(ai->sin_addr))) {
|
if (memcmp(&ai->sin_addr, &bi->sin_addr, sizeof(ai->sin_addr))) {
|
||||||
flags |= NGTCP2_ADDR_COMPARE_FLAG_ADDR;
|
flags |= NGTCP2_ADDR_CMP_FLAG_ADDR;
|
||||||
}
|
}
|
||||||
if (ai->sin_port != bi->sin_port) {
|
if (ai->sin_port != bi->sin_port) {
|
||||||
flags |= NGTCP2_ADDR_COMPARE_FLAG_PORT;
|
flags |= NGTCP2_ADDR_CMP_FLAG_PORT;
|
||||||
}
|
}
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
@ -102,10 +103,10 @@ uint32_t ngtcp2_addr_compare(const ngtcp2_addr *aa, const ngtcp2_addr *bb) {
|
||||||
const ngtcp2_sockaddr_in6 *ai = (const ngtcp2_sockaddr_in6 *)(void *)a,
|
const ngtcp2_sockaddr_in6 *ai = (const ngtcp2_sockaddr_in6 *)(void *)a,
|
||||||
*bi = (const ngtcp2_sockaddr_in6 *)(void *)b;
|
*bi = (const ngtcp2_sockaddr_in6 *)(void *)b;
|
||||||
if (memcmp(&ai->sin6_addr, &bi->sin6_addr, sizeof(ai->sin6_addr))) {
|
if (memcmp(&ai->sin6_addr, &bi->sin6_addr, sizeof(ai->sin6_addr))) {
|
||||||
flags |= NGTCP2_ADDR_COMPARE_FLAG_ADDR;
|
flags |= NGTCP2_ADDR_CMP_FLAG_ADDR;
|
||||||
}
|
}
|
||||||
if (ai->sin6_port != bi->sin6_port) {
|
if (ai->sin6_port != bi->sin6_port) {
|
||||||
flags |= NGTCP2_ADDR_COMPARE_FLAG_PORT;
|
flags |= NGTCP2_ADDR_CMP_FLAG_PORT;
|
||||||
}
|
}
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
30
deps/ngtcp2/ngtcp2/lib/ngtcp2_addr.h
vendored
30
deps/ngtcp2/ngtcp2/lib/ngtcp2_addr.h
vendored
|
|
@ -45,22 +45,21 @@ void ngtcp2_addr_copy(ngtcp2_addr *dest, const ngtcp2_addr *src);
|
||||||
*/
|
*/
|
||||||
int ngtcp2_addr_eq(const ngtcp2_addr *a, const ngtcp2_addr *b);
|
int ngtcp2_addr_eq(const ngtcp2_addr *a, const ngtcp2_addr *b);
|
||||||
|
|
||||||
/* NGTCP2_ADDR_COMPARE_FLAG_NONE indicates that no flag set. */
|
/* NGTCP2_ADDR_CMP_FLAG_NONE indicates that no flag set. */
|
||||||
#define NGTCP2_ADDR_COMPARE_FLAG_NONE 0x0u
|
#define NGTCP2_ADDR_CMP_FLAG_NONE 0x0u
|
||||||
/* NGTCP2_ADDR_COMPARE_FLAG_ADDR indicates IP addresses do not
|
/* NGTCP2_ADDR_CMP_FLAG_ADDR indicates IP addresses do not match. */
|
||||||
|
#define NGTCP2_ADDR_CMP_FLAG_ADDR 0x1u
|
||||||
|
/* NGTCP2_ADDR_CMP_FLAG_PORT indicates ports do not match. */
|
||||||
|
#define NGTCP2_ADDR_CMP_FLAG_PORT 0x2u
|
||||||
|
/* NGTCP2_ADDR_CMP_FLAG_FAMILY indicates address families do not
|
||||||
match. */
|
match. */
|
||||||
#define NGTCP2_ADDR_COMPARE_FLAG_ADDR 0x1u
|
#define NGTCP2_ADDR_CMP_FLAG_FAMILY 0x4u
|
||||||
/* NGTCP2_ADDR_COMPARE_FLAG_PORT indicates ports do not match. */
|
|
||||||
#define NGTCP2_ADDR_COMPARE_FLAG_PORT 0x2u
|
|
||||||
/* NGTCP2_ADDR_COMPARE_FLAG_FAMILY indicates address families do not
|
|
||||||
match. */
|
|
||||||
#define NGTCP2_ADDR_COMPARE_FLAG_FAMILY 0x4u
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_addr_compare compares address and port between |a| and |b|,
|
* ngtcp2_addr_cmp compares address and port between |a| and |b|, and
|
||||||
* and returns zero or more of NGTCP2_ADDR_COMPARE_FLAG_*.
|
* returns zero or more of NGTCP2_ADDR_CMP_FLAG_*.
|
||||||
*/
|
*/
|
||||||
uint32_t ngtcp2_addr_compare(const ngtcp2_addr *a, const ngtcp2_addr *b);
|
uint32_t ngtcp2_addr_cmp(const ngtcp2_addr *a, const ngtcp2_addr *b);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_addr_empty returns nonzero if |addr| has zero length
|
* ngtcp2_addr_empty returns nonzero if |addr| has zero length
|
||||||
|
|
@ -68,4 +67,11 @@ uint32_t ngtcp2_addr_compare(const ngtcp2_addr *a, const ngtcp2_addr *b);
|
||||||
*/
|
*/
|
||||||
int ngtcp2_addr_empty(const ngtcp2_addr *addr);
|
int ngtcp2_addr_empty(const ngtcp2_addr *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* `ngtcp2_sockaddr_eq` returns nonzero if |a| equals |b|.
|
||||||
|
*/
|
||||||
|
int ngtcp2_sockaddr_eq(const ngtcp2_sockaddr *a, const ngtcp2_sockaddr *b);
|
||||||
|
|
||||||
#endif /* !defined(NGTCP2_ADDR_H) */
|
#endif /* !defined(NGTCP2_ADDR_H) */
|
||||||
|
|
|
||||||
79
deps/ngtcp2/ngtcp2/lib/ngtcp2_bbr.c
vendored
79
deps/ngtcp2/ngtcp2/lib/ngtcp2_bbr.c
vendored
|
|
@ -39,7 +39,7 @@
|
||||||
#define NGTCP2_BBR_EXTRA_ACKED_FILTERLEN 10
|
#define NGTCP2_BBR_EXTRA_ACKED_FILTERLEN 10
|
||||||
|
|
||||||
#define NGTCP2_BBR_STARTUP_PACING_GAIN_H 277
|
#define NGTCP2_BBR_STARTUP_PACING_GAIN_H 277
|
||||||
#define NGTCP2_BBR_DRAIN_PACING_GAIN_H 35
|
#define NGTCP2_BBR_DRAIN_PACING_GAIN_H 50
|
||||||
|
|
||||||
#define NGTCP2_BBR_DEFAULT_CWND_GAIN_H 200
|
#define NGTCP2_BBR_DEFAULT_CWND_GAIN_H 200
|
||||||
|
|
||||||
|
|
@ -130,6 +130,8 @@ static void bbr_start_round(ngtcp2_cc_bbr *bbr);
|
||||||
|
|
||||||
static int bbr_is_in_probe_bw_state(ngtcp2_cc_bbr *bbr);
|
static int bbr_is_in_probe_bw_state(ngtcp2_cc_bbr *bbr);
|
||||||
|
|
||||||
|
static int bbr_is_probing_bw(ngtcp2_cc_bbr *bbr);
|
||||||
|
|
||||||
static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
|
static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
|
||||||
ngtcp2_conn_stat *cstat,
|
ngtcp2_conn_stat *cstat,
|
||||||
const ngtcp2_cc_ack *ack,
|
const ngtcp2_cc_ack *ack,
|
||||||
|
|
@ -137,8 +139,8 @@ static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
|
||||||
|
|
||||||
static void bbr_enter_drain(ngtcp2_cc_bbr *bbr);
|
static void bbr_enter_drain(ngtcp2_cc_bbr *bbr);
|
||||||
|
|
||||||
static void bbr_check_drain(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
static void bbr_check_drain_done(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||||
ngtcp2_tstamp ts);
|
ngtcp2_tstamp ts);
|
||||||
|
|
||||||
static void bbr_enter_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts);
|
static void bbr_enter_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts);
|
||||||
|
|
||||||
|
|
@ -277,7 +279,8 @@ static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||||
ngtcp2_window_filter_init(&bbr->extra_acked_filter,
|
ngtcp2_window_filter_init(&bbr->extra_acked_filter,
|
||||||
NGTCP2_BBR_EXTRA_ACKED_FILTERLEN);
|
NGTCP2_BBR_EXTRA_ACKED_FILTERLEN);
|
||||||
|
|
||||||
bbr->min_rtt = UINT64_MAX;
|
bbr->min_rtt =
|
||||||
|
cstat->first_rtt_sample_ts == UINT64_MAX ? UINT64_MAX : cstat->smoothed_rtt;
|
||||||
bbr->min_rtt_stamp = initial_ts;
|
bbr->min_rtt_stamp = initial_ts;
|
||||||
/* remark: Use UINT64_MAX instead of 0 for consistency. */
|
/* remark: Use UINT64_MAX instead of 0 for consistency. */
|
||||||
bbr->probe_rtt_done_stamp = UINT64_MAX;
|
bbr->probe_rtt_done_stamp = UINT64_MAX;
|
||||||
|
|
@ -335,6 +338,8 @@ static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||||
bbr->max_inflight = 0;
|
bbr->max_inflight = 0;
|
||||||
|
|
||||||
bbr->congestion_recovery_start_ts = UINT64_MAX;
|
bbr->congestion_recovery_start_ts = UINT64_MAX;
|
||||||
|
|
||||||
|
bbr->bdp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bbr_reset_congestion_signals(ngtcp2_cc_bbr *bbr) {
|
static void bbr_reset_congestion_signals(ngtcp2_cc_bbr *bbr) {
|
||||||
|
|
@ -404,8 +409,10 @@ static void bbr_check_startup_high_loss(ngtcp2_cc_bbr *bbr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bbr_init_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
|
static void bbr_init_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
|
||||||
cstat->pacing_interval = NGTCP2_MILLISECONDS * 100 /
|
cstat->pacing_interval =
|
||||||
NGTCP2_BBR_STARTUP_PACING_GAIN_H / bbr->initial_cwnd;
|
(cstat->first_rtt_sample_ts == UINT64_MAX ? NGTCP2_MILLISECONDS
|
||||||
|
: cstat->smoothed_rtt) *
|
||||||
|
100 / NGTCP2_BBR_STARTUP_PACING_GAIN_H / bbr->initial_cwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bbr_set_pacing_rate_with_gain(ngtcp2_cc_bbr *bbr,
|
static void bbr_set_pacing_rate_with_gain(ngtcp2_cc_bbr *bbr,
|
||||||
|
|
@ -465,7 +472,7 @@ static void bbr_update_model_and_state(ngtcp2_cc_bbr *bbr,
|
||||||
bbr_update_ack_aggregation(bbr, cstat, ack, ts);
|
bbr_update_ack_aggregation(bbr, cstat, ack, ts);
|
||||||
bbr_check_full_bw_reached(bbr, cstat);
|
bbr_check_full_bw_reached(bbr, cstat);
|
||||||
bbr_check_startup_done(bbr);
|
bbr_check_startup_done(bbr);
|
||||||
bbr_check_drain(bbr, cstat, ts);
|
bbr_check_drain_done(bbr, cstat, ts);
|
||||||
bbr_update_probe_bw_cycle_phase(bbr, cstat, ack, ts);
|
bbr_update_probe_bw_cycle_phase(bbr, cstat, ack, ts);
|
||||||
bbr_update_min_rtt(bbr, ack, ts);
|
bbr_update_min_rtt(bbr, ack, ts);
|
||||||
bbr_check_probe_rtt(bbr, cstat, ts);
|
bbr_check_probe_rtt(bbr, cstat, ts);
|
||||||
|
|
@ -528,7 +535,7 @@ static void bbr_update_congestion_signals(ngtcp2_cc_bbr *bbr,
|
||||||
|
|
||||||
static void bbr_adapt_lower_bounds_from_congestion(ngtcp2_cc_bbr *bbr,
|
static void bbr_adapt_lower_bounds_from_congestion(ngtcp2_cc_bbr *bbr,
|
||||||
ngtcp2_conn_stat *cstat) {
|
ngtcp2_conn_stat *cstat) {
|
||||||
if (bbr_is_in_probe_bw_state(bbr)) {
|
if (bbr_is_probing_bw(bbr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -607,6 +614,17 @@ static int bbr_is_in_probe_bw_state(ngtcp2_cc_bbr *bbr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bbr_is_probing_bw(ngtcp2_cc_bbr *bbr) {
|
||||||
|
switch (bbr->state) {
|
||||||
|
case NGTCP2_BBR_STATE_STARTUP:
|
||||||
|
case NGTCP2_BBR_STATE_PROBE_BW_REFILL:
|
||||||
|
case NGTCP2_BBR_STATE_PROBE_BW_UP:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
|
static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
|
||||||
ngtcp2_conn_stat *cstat,
|
ngtcp2_conn_stat *cstat,
|
||||||
const ngtcp2_cc_ack *ack,
|
const ngtcp2_cc_ack *ack,
|
||||||
|
|
@ -622,8 +640,13 @@ static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
|
||||||
}
|
}
|
||||||
|
|
||||||
bbr->extra_acked_delivered += ack->bytes_delivered;
|
bbr->extra_acked_delivered += ack->bytes_delivered;
|
||||||
extra = bbr->extra_acked_delivered - expected_delivered;
|
|
||||||
extra = ngtcp2_min_uint64(extra, cstat->cwnd);
|
if (bbr->extra_acked_delivered <= expected_delivered) {
|
||||||
|
extra = 0;
|
||||||
|
} else {
|
||||||
|
extra = bbr->extra_acked_delivered - expected_delivered;
|
||||||
|
extra = ngtcp2_min_uint64(extra, cstat->cwnd);
|
||||||
|
}
|
||||||
|
|
||||||
if (bbr->full_bw_reached) {
|
if (bbr->full_bw_reached) {
|
||||||
bbr->extra_acked_filter.window_length = NGTCP2_BBR_EXTRA_ACKED_FILTERLEN;
|
bbr->extra_acked_filter.window_length = NGTCP2_BBR_EXTRA_ACKED_FILTERLEN;
|
||||||
|
|
@ -645,8 +668,8 @@ static void bbr_enter_drain(ngtcp2_cc_bbr *bbr) {
|
||||||
bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
|
bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bbr_check_drain(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
static void bbr_check_drain_done(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||||
ngtcp2_tstamp ts) {
|
ngtcp2_tstamp ts) {
|
||||||
if (bbr->state == NGTCP2_BBR_STATE_DRAIN &&
|
if (bbr->state == NGTCP2_BBR_STATE_DRAIN &&
|
||||||
cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, 100)) {
|
cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, 100)) {
|
||||||
bbr_enter_probe_bw(bbr, ts);
|
bbr_enter_probe_bw(bbr, ts);
|
||||||
|
|
@ -825,8 +848,7 @@ static void bbr_raise_inflight_hi_slope(ngtcp2_cc_bbr *bbr,
|
||||||
<< bbr->bw_probe_up_rounds;
|
<< bbr->bw_probe_up_rounds;
|
||||||
|
|
||||||
bbr->bw_probe_up_rounds = ngtcp2_min_size(bbr->bw_probe_up_rounds + 1, 30);
|
bbr->bw_probe_up_rounds = ngtcp2_min_size(bbr->bw_probe_up_rounds + 1, 30);
|
||||||
bbr->probe_up_cnt = ngtcp2_max_uint64(cstat->cwnd / growth_this_round, 1) *
|
bbr->probe_up_cnt = ngtcp2_max_uint64(cstat->cwnd / growth_this_round, 1);
|
||||||
cstat->max_tx_udp_payload_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
|
static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
|
||||||
|
|
@ -840,10 +862,12 @@ static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
|
||||||
|
|
||||||
bbr->bw_probe_up_acks += ack->bytes_delivered;
|
bbr->bw_probe_up_acks += ack->bytes_delivered;
|
||||||
|
|
||||||
if (bbr->bw_probe_up_acks >= bbr->probe_up_cnt) {
|
if (bbr->probe_up_cnt != UINT64_MAX &&
|
||||||
|
bbr->bw_probe_up_acks >=
|
||||||
|
bbr->probe_up_cnt * cstat->max_tx_udp_payload_size) {
|
||||||
delta = bbr->bw_probe_up_acks / bbr->probe_up_cnt;
|
delta = bbr->bw_probe_up_acks / bbr->probe_up_cnt;
|
||||||
bbr->bw_probe_up_acks -= delta * bbr->probe_up_cnt;
|
bbr->bw_probe_up_acks -= delta * bbr->probe_up_cnt;
|
||||||
bbr->inflight_hi += delta * cstat->max_tx_udp_payload_size;
|
bbr->inflight_hi += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bbr->round_start) {
|
if (bbr->round_start) {
|
||||||
|
|
@ -901,8 +925,7 @@ static void bbr_pick_probe_wait(ngtcp2_cc_bbr *bbr) {
|
||||||
|
|
||||||
bbr->rand(&rand, 1, &bbr->rand_ctx);
|
bbr->rand(&rand, 1, &bbr->rand_ctx);
|
||||||
|
|
||||||
bbr->bw_probe_wait =
|
bbr->bw_probe_wait = 2 * NGTCP2_SECONDS + NGTCP2_SECONDS * rand / 255;
|
||||||
2 * NGTCP2_SECONDS + (ngtcp2_tstamp)(NGTCP2_SECONDS * rand / 255);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bbr_is_reno_coexistence_probe_time(ngtcp2_cc_bbr *bbr,
|
static int bbr_is_reno_coexistence_probe_time(ngtcp2_cc_bbr *bbr,
|
||||||
|
|
@ -915,9 +938,7 @@ static int bbr_is_reno_coexistence_probe_time(ngtcp2_cc_bbr *bbr,
|
||||||
|
|
||||||
static uint64_t bbr_target_inflight(ngtcp2_cc_bbr *bbr,
|
static uint64_t bbr_target_inflight(ngtcp2_cc_bbr *bbr,
|
||||||
ngtcp2_conn_stat *cstat) {
|
ngtcp2_conn_stat *cstat) {
|
||||||
uint64_t bdp = bbr_bdp_multiple(bbr, bbr->cwnd_gain_h);
|
return ngtcp2_min_uint64(bbr->bdp, cstat->cwnd);
|
||||||
|
|
||||||
return ngtcp2_min_uint64(bdp, cstat->cwnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bbr_check_inflight_too_high(ngtcp2_cc_bbr *bbr,
|
static int bbr_check_inflight_too_high(ngtcp2_cc_bbr *bbr,
|
||||||
|
|
@ -957,12 +978,11 @@ static void bbr_handle_inflight_too_high(ngtcp2_cc_bbr *bbr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bbr_note_loss(ngtcp2_cc_bbr *bbr) {
|
static void bbr_note_loss(ngtcp2_cc_bbr *bbr) {
|
||||||
if (bbr->loss_in_round) {
|
if (!bbr->loss_in_round) {
|
||||||
return;
|
bbr->loss_round_delivered = bbr->rst->delivered;
|
||||||
}
|
}
|
||||||
|
|
||||||
bbr->loss_in_round = 1;
|
bbr->loss_in_round = 1;
|
||||||
bbr->loss_round_delivered = bbr->rst->delivered;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||||
|
|
@ -977,6 +997,7 @@ static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
|
||||||
|
|
||||||
rs.tx_in_flight = pkt->tx_in_flight;
|
rs.tx_in_flight = pkt->tx_in_flight;
|
||||||
/* bbr->rst->lost is not incremented for pkt yet */
|
/* 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.lost = bbr->rst->lost + pkt->pktlen - pkt->lost;
|
||||||
rs.is_app_limited = pkt->is_app_limited;
|
rs.is_app_limited = pkt->is_app_limited;
|
||||||
|
|
||||||
|
|
@ -1143,15 +1164,13 @@ static void bbr_handle_restart_from_idle(ngtcp2_cc_bbr *bbr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t gain_h) {
|
static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t gain_h) {
|
||||||
uint64_t bdp;
|
|
||||||
|
|
||||||
if (bbr->min_rtt == UINT64_MAX) {
|
if (bbr->min_rtt == UINT64_MAX) {
|
||||||
return bbr->initial_cwnd;
|
return bbr->initial_cwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bdp = ngtcp2_max_uint64(bbr->bw * bbr->min_rtt / NGTCP2_SECONDS, 1);
|
bbr->bdp = ngtcp2_max_uint64(bbr->bw * bbr->min_rtt / NGTCP2_SECONDS, 1);
|
||||||
|
|
||||||
return (uint64_t)(bdp * gain_h / 100);
|
return (uint64_t)(bbr->bdp * gain_h / 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t min_pipe_cwnd(size_t max_udp_payload_size) {
|
static uint64_t min_pipe_cwnd(size_t max_udp_payload_size) {
|
||||||
|
|
@ -1324,10 +1343,6 @@ static void bbr_cc_on_pkt_lost(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
||||||
const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
|
const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
|
||||||
ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
|
ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
|
||||||
|
|
||||||
if (bbr->state == NGTCP2_BBR_STATE_STARTUP) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bbr_update_on_loss(bbr, cstat, pkt, ts);
|
bbr_update_on_loss(bbr, cstat, pkt, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1
deps/ngtcp2/ngtcp2/lib/ngtcp2_bbr.h
vendored
1
deps/ngtcp2/ngtcp2/lib/ngtcp2_bbr.h
vendored
|
|
@ -131,6 +131,7 @@ typedef struct ngtcp2_cc_bbr {
|
||||||
uint64_t round_count_at_recovery;
|
uint64_t round_count_at_recovery;
|
||||||
uint64_t max_inflight;
|
uint64_t max_inflight;
|
||||||
ngtcp2_tstamp congestion_recovery_start_ts;
|
ngtcp2_tstamp congestion_recovery_start_ts;
|
||||||
|
uint64_t bdp;
|
||||||
} ngtcp2_cc_bbr;
|
} ngtcp2_cc_bbr;
|
||||||
|
|
||||||
void ngtcp2_cc_bbr_init(ngtcp2_cc_bbr *bbr, ngtcp2_log *log,
|
void ngtcp2_cc_bbr_init(ngtcp2_cc_bbr *bbr, ngtcp2_log *log,
|
||||||
|
|
|
||||||
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c
vendored
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c
vendored
|
|
@ -252,13 +252,15 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
||||||
uint64_t w_cubic, w_cubic_next, target, m;
|
uint64_t w_cubic, w_cubic_next, target, m;
|
||||||
ngtcp2_duration rtt_thresh;
|
ngtcp2_duration rtt_thresh;
|
||||||
int round_start;
|
int round_start;
|
||||||
|
int is_app_limited =
|
||||||
|
cubic->rst->rs.is_app_limited && !cubic->rst->is_cwnd_limited;
|
||||||
|
|
||||||
if (in_congestion_recovery(cstat, ack->largest_pkt_sent_ts)) {
|
if (in_congestion_recovery(cstat, ack->largest_pkt_sent_ts)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cubic->current.state == NGTCP2_CUBIC_STATE_CONGESTION_AVOIDANCE) {
|
if (cubic->current.state == NGTCP2_CUBIC_STATE_CONGESTION_AVOIDANCE) {
|
||||||
if (cubic->rst->rs.is_app_limited && !cubic->rst->is_cwnd_limited) {
|
if (is_app_limited) {
|
||||||
if (cubic->current.app_limited_start_ts == UINT64_MAX) {
|
if (cubic->current.app_limited_start_ts == UINT64_MAX) {
|
||||||
cubic->current.app_limited_start_ts = ts;
|
cubic->current.app_limited_start_ts = ts;
|
||||||
}
|
}
|
||||||
|
|
@ -271,7 +273,7 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
|
||||||
ts - cubic->current.app_limited_start_ts;
|
ts - cubic->current.app_limited_start_ts;
|
||||||
cubic->current.app_limited_start_ts = UINT64_MAX;
|
cubic->current.app_limited_start_ts = UINT64_MAX;
|
||||||
}
|
}
|
||||||
} else if (cubic->rst->rs.is_app_limited && !cubic->rst->is_cwnd_limited) {
|
} else if (is_app_limited) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
deps/ngtcp2/ngtcp2/lib/ngtcp2_cid.c
vendored
4
deps/ngtcp2/ngtcp2/lib/ngtcp2_cid.c
vendored
|
|
@ -141,8 +141,10 @@ int ngtcp2_dcid_verify_uniqueness(const ngtcp2_dcid *dcid, uint64_t seq,
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_dcid_verify_stateless_reset_token(const ngtcp2_dcid *dcid,
|
int ngtcp2_dcid_verify_stateless_reset_token(const ngtcp2_dcid *dcid,
|
||||||
|
const ngtcp2_path *path,
|
||||||
const uint8_t *token) {
|
const uint8_t *token) {
|
||||||
return (dcid->flags & NGTCP2_DCID_FLAG_TOKEN_PRESENT) &&
|
return ngtcp2_path_eq(&dcid->ps.path, path) &&
|
||||||
|
(dcid->flags & NGTCP2_DCID_FLAG_TOKEN_PRESENT) &&
|
||||||
ngtcp2_cmemeq(dcid->token, token, NGTCP2_STATELESS_RESET_TOKENLEN)
|
ngtcp2_cmemeq(dcid->token, token, NGTCP2_STATELESS_RESET_TOKENLEN)
|
||||||
? 0
|
? 0
|
||||||
: NGTCP2_ERR_INVALID_ARGUMENT;
|
: NGTCP2_ERR_INVALID_ARGUMENT;
|
||||||
|
|
|
||||||
13
deps/ngtcp2/ngtcp2/lib/ngtcp2_cid.h
vendored
13
deps/ngtcp2/ngtcp2/lib/ngtcp2_cid.h
vendored
|
|
@ -149,7 +149,9 @@ void ngtcp2_dcid_copy(ngtcp2_dcid *dest, const ngtcp2_dcid *src);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_dcid_copy_cid_token behaves like ngtcp2_dcid_copy, but it
|
* ngtcp2_dcid_copy_cid_token behaves like ngtcp2_dcid_copy, but it
|
||||||
* only copies cid, seq, and token.
|
* only copies cid, seq, and token. dest->flags should be initialized
|
||||||
|
* before this call because NGTCP2_DCID_FLAG_TOKEN_PRESENT is set or
|
||||||
|
* unset.
|
||||||
*/
|
*/
|
||||||
void ngtcp2_dcid_copy_cid_token(ngtcp2_dcid *dest, const ngtcp2_dcid *src);
|
void ngtcp2_dcid_copy_cid_token(ngtcp2_dcid *dest, const ngtcp2_dcid *src);
|
||||||
|
|
||||||
|
|
@ -162,15 +164,16 @@ int ngtcp2_dcid_verify_uniqueness(const ngtcp2_dcid *dcid, uint64_t seq,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_dcid_verify_stateless_reset_token verifies stateless reset
|
* ngtcp2_dcid_verify_stateless_reset_token verifies stateless reset
|
||||||
* token |token| against the one included in |dcid|. Tokens are
|
* token |token| received on |path| against the one included in
|
||||||
* compared in constant time. This function returns 0 if the
|
* |dcid|. Tokens are compared in constant time. This function
|
||||||
* verification succeeds, or one of the following negative error
|
* returns 0 if the verification succeeds, or one of the following
|
||||||
* codes:
|
* negative error codes:
|
||||||
*
|
*
|
||||||
* NGTCP2_ERR_INVALID_ARGUMENT
|
* NGTCP2_ERR_INVALID_ARGUMENT
|
||||||
* Tokens do not match; or |dcid| does not contain a token.
|
* Tokens do not match; or |dcid| does not contain a token.
|
||||||
*/
|
*/
|
||||||
int ngtcp2_dcid_verify_stateless_reset_token(const ngtcp2_dcid *dcid,
|
int ngtcp2_dcid_verify_stateless_reset_token(const ngtcp2_dcid *dcid,
|
||||||
|
const ngtcp2_path *path,
|
||||||
const uint8_t *token);
|
const uint8_t *token);
|
||||||
|
|
||||||
#endif /* !defined(NGTCP2_CID_H) */
|
#endif /* !defined(NGTCP2_CID_H) */
|
||||||
|
|
|
||||||
1296
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c
vendored
1296
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c
vendored
File diff suppressed because it is too large
Load Diff
121
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.h
vendored
121
deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.h
vendored
|
|
@ -51,6 +51,7 @@
|
||||||
#include "ngtcp2_qlog.h"
|
#include "ngtcp2_qlog.h"
|
||||||
#include "ngtcp2_rst.h"
|
#include "ngtcp2_rst.h"
|
||||||
#include "ngtcp2_conn_stat.h"
|
#include "ngtcp2_conn_stat.h"
|
||||||
|
#include "ngtcp2_dcidtr.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* Client specific handshake states */
|
/* Client specific handshake states */
|
||||||
|
|
@ -78,18 +79,6 @@ typedef enum {
|
||||||
accept. */
|
accept. */
|
||||||
#define NGTCP2_MAX_RETRIES 3
|
#define NGTCP2_MAX_RETRIES 3
|
||||||
|
|
||||||
/* NGTCP2_MAX_BOUND_DCID_POOL_SIZE is the maximum number of
|
|
||||||
destination connection ID which have been bound to a particular
|
|
||||||
path, but not yet used as primary path and path validation is not
|
|
||||||
performed from the local endpoint. */
|
|
||||||
#define NGTCP2_MAX_BOUND_DCID_POOL_SIZE 4
|
|
||||||
/* NGTCP2_MAX_DCID_POOL_SIZE is the maximum number of destination
|
|
||||||
connection ID the remote endpoint provides to store. It must be
|
|
||||||
the power of 2. */
|
|
||||||
#define NGTCP2_MAX_DCID_POOL_SIZE 8
|
|
||||||
/* NGTCP2_MAX_DCID_RETIRED_SIZE is the maximum number of retired DCID
|
|
||||||
kept to catch in-flight packet on retired path. */
|
|
||||||
#define NGTCP2_MAX_DCID_RETIRED_SIZE 2
|
|
||||||
/* NGTCP2_MAX_SCID_POOL_SIZE is the maximum number of source
|
/* NGTCP2_MAX_SCID_POOL_SIZE is the maximum number of source
|
||||||
connection ID the local endpoint provides to the remote endpoint.
|
connection ID the local endpoint provides to the remote endpoint.
|
||||||
The chosen value was described in old draft. Now a remote endpoint
|
The chosen value was described in old draft. Now a remote endpoint
|
||||||
|
|
@ -239,11 +228,6 @@ typedef struct ngtcp2_pktns {
|
||||||
/* pngap tracks received packet number in order to suppress
|
/* pngap tracks received packet number in order to suppress
|
||||||
duplicated packet number. */
|
duplicated packet number. */
|
||||||
ngtcp2_gaptr pngap;
|
ngtcp2_gaptr pngap;
|
||||||
/* max_pkt_num is the largest packet number received so far. */
|
|
||||||
int64_t max_pkt_num;
|
|
||||||
/* max_pkt_ts is the timestamp when max_pkt_num packet is
|
|
||||||
received. */
|
|
||||||
ngtcp2_tstamp max_pkt_ts;
|
|
||||||
/* max_ack_eliciting_pkt_num is the largest ack-eliciting packet
|
/* max_ack_eliciting_pkt_num is the largest ack-eliciting packet
|
||||||
number received so far. */
|
number received so far. */
|
||||||
int64_t max_ack_eliciting_pkt_num;
|
int64_t max_ack_eliciting_pkt_num;
|
||||||
|
|
@ -268,21 +252,6 @@ typedef struct ngtcp2_pktns {
|
||||||
* ngtcp2_pktns.
|
* ngtcp2_pktns.
|
||||||
*/
|
*/
|
||||||
ngtcp2_pkt_chain *buffed_pkts;
|
ngtcp2_pkt_chain *buffed_pkts;
|
||||||
|
|
||||||
struct {
|
|
||||||
/* ect0, ect1, and ce are the number of QUIC packets received
|
|
||||||
with those markings. */
|
|
||||||
size_t ect0;
|
|
||||||
size_t ect1;
|
|
||||||
size_t ce;
|
|
||||||
struct {
|
|
||||||
/* ect0, ect1, ce are the ECN counts received in the latest
|
|
||||||
ACK frame. */
|
|
||||||
uint64_t ect0;
|
|
||||||
uint64_t ect1;
|
|
||||||
uint64_t ce;
|
|
||||||
} ack;
|
|
||||||
} ecn;
|
|
||||||
} rx;
|
} rx;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -336,12 +305,6 @@ typedef struct ngtcp2_early_transport_params {
|
||||||
uint64_t max_datagram_frame_size;
|
uint64_t max_datagram_frame_size;
|
||||||
} ngtcp2_early_transport_params;
|
} ngtcp2_early_transport_params;
|
||||||
|
|
||||||
ngtcp2_static_ringbuf_def(dcid_bound, NGTCP2_MAX_BOUND_DCID_POOL_SIZE,
|
|
||||||
sizeof(ngtcp2_dcid))
|
|
||||||
ngtcp2_static_ringbuf_def(dcid_unused, NGTCP2_MAX_DCID_POOL_SIZE,
|
|
||||||
sizeof(ngtcp2_dcid))
|
|
||||||
ngtcp2_static_ringbuf_def(dcid_retired, NGTCP2_MAX_DCID_RETIRED_SIZE,
|
|
||||||
sizeof(ngtcp2_dcid))
|
|
||||||
ngtcp2_static_ringbuf_def(path_challenge, 4,
|
ngtcp2_static_ringbuf_def(path_challenge, 4,
|
||||||
sizeof(ngtcp2_path_challenge_entry))
|
sizeof(ngtcp2_path_challenge_entry))
|
||||||
|
|
||||||
|
|
@ -366,6 +329,8 @@ struct ngtcp2_conn {
|
||||||
records it in order to verify retry_source_connection_id
|
records it in order to verify retry_source_connection_id
|
||||||
transport parameter. Server does not use this field. */
|
transport parameter. Server does not use this field. */
|
||||||
ngtcp2_cid retry_scid;
|
ngtcp2_cid retry_scid;
|
||||||
|
/* hs_local_addr is a local address used during handshake. */
|
||||||
|
ngtcp2_sockaddr_union hs_local_addr;
|
||||||
ngtcp2_pktns *in_pktns;
|
ngtcp2_pktns *in_pktns;
|
||||||
ngtcp2_pktns *hs_pktns;
|
ngtcp2_pktns *hs_pktns;
|
||||||
ngtcp2_pktns pktns;
|
ngtcp2_pktns pktns;
|
||||||
|
|
@ -373,31 +338,13 @@ struct ngtcp2_conn {
|
||||||
struct {
|
struct {
|
||||||
/* current is the current destination connection ID. */
|
/* current is the current destination connection ID. */
|
||||||
ngtcp2_dcid current;
|
ngtcp2_dcid current;
|
||||||
/* bound is a set of destination connection IDs which are bound to
|
ngtcp2_dcidtr dtr;
|
||||||
particular paths. These paths are not validated yet. */
|
|
||||||
ngtcp2_static_ringbuf_dcid_bound bound;
|
|
||||||
/* unused is a set of unused CID received from peer. */
|
|
||||||
ngtcp2_static_ringbuf_dcid_unused unused;
|
|
||||||
/* retired is a set of CID retired by local endpoint. Keep them
|
|
||||||
in 3*PTO to catch packets in flight along the old path. */
|
|
||||||
ngtcp2_static_ringbuf_dcid_retired retired;
|
|
||||||
/* seqgap tracks received sequence numbers in order to ignore
|
/* seqgap tracks received sequence numbers in order to ignore
|
||||||
retransmitted duplicated NEW_CONNECTION_ID frame. */
|
retransmitted duplicated NEW_CONNECTION_ID frame. */
|
||||||
ngtcp2_gaptr seqgap;
|
ngtcp2_gaptr seqgap;
|
||||||
/* retire_prior_to is the largest retire_prior_to received so
|
/* retire_prior_to is the largest retire_prior_to received so
|
||||||
far. */
|
far. */
|
||||||
uint64_t retire_prior_to;
|
uint64_t retire_prior_to;
|
||||||
struct {
|
|
||||||
/* seqs contains sequence number of Connection ID whose
|
|
||||||
retirement is not acknowledged by the remote endpoint yet. */
|
|
||||||
uint64_t seqs[NGTCP2_MAX_DCID_POOL_SIZE * 2];
|
|
||||||
/* len is the number of sequence numbers that seq contains. */
|
|
||||||
size_t len;
|
|
||||||
} retire_unacked;
|
|
||||||
/* zerolen_seq is a pseudo sequence number of zero-length
|
|
||||||
Destination Connection ID in order to distinguish between
|
|
||||||
them. */
|
|
||||||
uint64_t zerolen_seq;
|
|
||||||
} dcid;
|
} dcid;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -421,11 +368,6 @@ struct ngtcp2_conn {
|
||||||
struct {
|
struct {
|
||||||
/* strmq contains ngtcp2_strm which has frames to send. */
|
/* strmq contains ngtcp2_strm which has frames to send. */
|
||||||
ngtcp2_pq strmq;
|
ngtcp2_pq strmq;
|
||||||
/* ack is ACK frame. The underlying buffer is reused. */
|
|
||||||
ngtcp2_frame *ack;
|
|
||||||
/* max_ack_ranges is the number of additional ngtcp2_ack_range
|
|
||||||
which ack can contain. */
|
|
||||||
size_t max_ack_ranges;
|
|
||||||
/* offset is the offset the local endpoint has sent to the remote
|
/* offset is the offset the local endpoint has sent to the remote
|
||||||
endpoint. */
|
endpoint. */
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
|
|
@ -458,6 +400,15 @@ struct ngtcp2_conn {
|
||||||
/* next_ts is the time to send next packet. It is UINT64_MAX if
|
/* next_ts is the time to send next packet. It is UINT64_MAX if
|
||||||
packet pacing is disabled or expired.*/
|
packet pacing is disabled or expired.*/
|
||||||
ngtcp2_tstamp next_ts;
|
ngtcp2_tstamp next_ts;
|
||||||
|
/* compensation is the amount of time that a local endpoint
|
||||||
|
waits too long for pacing. This happens because there is an
|
||||||
|
overhead before start writing packets after pacing timer
|
||||||
|
expires. If multiple QUIC connections are handled by a
|
||||||
|
single thread, which is typical use case for event loop based
|
||||||
|
servers, each processing of QUIC connection adds overhead,
|
||||||
|
for example, TLS handshake, and packet encryption/decryption,
|
||||||
|
etc. */
|
||||||
|
ngtcp2_duration compensation;
|
||||||
} pacing;
|
} pacing;
|
||||||
} tx;
|
} tx;
|
||||||
|
|
||||||
|
|
@ -478,6 +429,12 @@ struct ngtcp2_conn {
|
||||||
ngtcp2_static_ringbuf_path_challenge path_challenge;
|
ngtcp2_static_ringbuf_path_challenge path_challenge;
|
||||||
/* ccerr is the received connection close error. */
|
/* ccerr is the received connection close error. */
|
||||||
ngtcp2_ccerr ccerr;
|
ngtcp2_ccerr ccerr;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
/* pkt_num is the lowest incoming packet number of the packet
|
||||||
|
that server verified preferred address usage of client. */
|
||||||
|
int64_t pkt_num;
|
||||||
|
} preferred_addr;
|
||||||
} rx;
|
} rx;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -671,6 +628,9 @@ struct ngtcp2_conn {
|
||||||
const ngtcp2_mem *mem;
|
const ngtcp2_mem *mem;
|
||||||
/* idle_ts is the time instant when idle timer started. */
|
/* idle_ts is the time instant when idle timer started. */
|
||||||
ngtcp2_tstamp idle_ts;
|
ngtcp2_tstamp idle_ts;
|
||||||
|
/* handshake_confirmed_ts is the time instant when handshake is
|
||||||
|
confirmed. For server, it is confirmed when completed. */
|
||||||
|
ngtcp2_tstamp handshake_confirmed_ts;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
uint32_t client_chosen_version;
|
uint32_t client_chosen_version;
|
||||||
uint32_t negotiated_version;
|
uint32_t negotiated_version;
|
||||||
|
|
@ -724,21 +684,6 @@ typedef struct ngtcp2_vmsg {
|
||||||
};
|
};
|
||||||
} ngtcp2_vmsg;
|
} ngtcp2_vmsg;
|
||||||
|
|
||||||
/*
|
|
||||||
* ngtcp2_conn_sched_ack stores packet number |pkt_num| and its
|
|
||||||
* reception timestamp |ts| in order to send its ACK.
|
|
||||||
*
|
|
||||||
* It returns 0 if it succeeds, or one of the following negative error
|
|
||||||
* codes:
|
|
||||||
*
|
|
||||||
* NGTCP2_ERR_NOMEM
|
|
||||||
* Out of memory
|
|
||||||
* NGTCP2_ERR_PROTO
|
|
||||||
* Same packet number has already been added.
|
|
||||||
*/
|
|
||||||
int ngtcp2_conn_sched_ack(ngtcp2_conn *conn, ngtcp2_acktr *acktr,
|
|
||||||
int64_t pkt_num, int active_ack, ngtcp2_tstamp ts);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_conn_find_stream returns a stream whose stream ID is
|
* ngtcp2_conn_find_stream returns a stream whose stream ID is
|
||||||
* |stream_id|. If no such stream is found, it returns NULL.
|
* |stream_id|. If no such stream is found, it returns NULL.
|
||||||
|
|
@ -1137,28 +1082,6 @@ int ngtcp2_conn_set_remote_transport_params(
|
||||||
int ngtcp2_conn_set_0rtt_remote_transport_params(
|
int ngtcp2_conn_set_0rtt_remote_transport_params(
|
||||||
ngtcp2_conn *conn, const ngtcp2_transport_params *params);
|
ngtcp2_conn *conn, const ngtcp2_transport_params *params);
|
||||||
|
|
||||||
/*
|
|
||||||
* ngtcp2_conn_create_ack_frame creates ACK frame, and assigns its
|
|
||||||
* pointer to |*pfr| if there are any received packets to acknowledge.
|
|
||||||
* If there are no packets to acknowledge, this function returns 0,
|
|
||||||
* and |*pfr| is untouched. The caller is advised to set |*pfr| to
|
|
||||||
* NULL before calling this function, and check it after this function
|
|
||||||
* returns.
|
|
||||||
*
|
|
||||||
* Call ngtcp2_acktr_commit_ack after a created ACK frame is
|
|
||||||
* successfully serialized into a packet.
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGTCP2_ERR_NOMEM
|
|
||||||
* Out of memory.
|
|
||||||
*/
|
|
||||||
int ngtcp2_conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
|
|
||||||
ngtcp2_pktns *pktns, uint8_t type,
|
|
||||||
ngtcp2_tstamp ts, ngtcp2_duration ack_delay,
|
|
||||||
uint64_t ack_delay_exponent);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_conn_discard_initial_state discards state for Initial packet
|
* ngtcp2_conn_discard_initial_state discards state for Initial packet
|
||||||
* number space.
|
* number space.
|
||||||
|
|
|
||||||
497
deps/ngtcp2/ngtcp2/lib/ngtcp2_dcidtr.c
vendored
Normal file
497
deps/ngtcp2/ngtcp2/lib/ngtcp2_dcidtr.c
vendored
Normal file
|
|
@ -0,0 +1,497 @@
|
||||||
|
/*
|
||||||
|
* 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_dcidtr.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "ngtcp2_tstamp.h"
|
||||||
|
#include "ngtcp2_macro.h"
|
||||||
|
|
||||||
|
void ngtcp2_dcidtr_init(ngtcp2_dcidtr *dtr) {
|
||||||
|
ngtcp2_static_ringbuf_dcid_unused_init(&dtr->unused);
|
||||||
|
ngtcp2_static_ringbuf_dcid_bound_init(&dtr->bound);
|
||||||
|
ngtcp2_static_ringbuf_dcid_retired_init(&dtr->retired);
|
||||||
|
|
||||||
|
dtr->retire_unacked.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_track_retired_seq(ngtcp2_dcidtr *dtr, uint64_t seq) {
|
||||||
|
if (dtr->retire_unacked.len >= ngtcp2_arraylen(dtr->retire_unacked.seqs)) {
|
||||||
|
return NGTCP2_ERR_CONNECTION_ID_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
dtr->retire_unacked.seqs[dtr->retire_unacked.len++] = seq;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngtcp2_dcidtr_untrack_retired_seq(ngtcp2_dcidtr *dtr, uint64_t seq) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < dtr->retire_unacked.len; ++i) {
|
||||||
|
if (dtr->retire_unacked.seqs[i] != seq) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != dtr->retire_unacked.len - 1) {
|
||||||
|
dtr->retire_unacked.seqs[i] =
|
||||||
|
dtr->retire_unacked.seqs[dtr->retire_unacked.len - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
--dtr->retire_unacked.len;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_check_retired_seq_tracked(const ngtcp2_dcidtr *dtr,
|
||||||
|
uint64_t seq) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < dtr->retire_unacked.len; ++i) {
|
||||||
|
if (dtr->retire_unacked.seqs[i] == seq) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dcidtr_on_retire(ngtcp2_dcidtr *dtr, const ngtcp2_dcid *dcid,
|
||||||
|
ngtcp2_dcidtr_cb on_retire, void *user_data) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (ngtcp2_dcidtr_check_retired_seq_tracked(dtr, dcid->seq)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = ngtcp2_dcidtr_track_retired_seq(dtr, dcid->seq);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!on_retire) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return on_retire(dcid, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngtcp2_dcid *ngtcp2_dcidtr_find_bound_dcid(const ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_path *path) {
|
||||||
|
ngtcp2_dcid *dcid;
|
||||||
|
const ngtcp2_ringbuf *rb = &dtr->bound.rb;
|
||||||
|
size_t i, len = ngtcp2_ringbuf_len(rb);
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, i);
|
||||||
|
|
||||||
|
if (ngtcp2_path_eq(&dcid->ps.path, path)) {
|
||||||
|
return dcid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngtcp2_dcid *ngtcp2_dcidtr_bind_zerolen_dcid(ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_path *path) {
|
||||||
|
ngtcp2_dcid *dcid = ngtcp2_ringbuf_push_back(&dtr->bound.rb);
|
||||||
|
ngtcp2_cid cid;
|
||||||
|
|
||||||
|
ngtcp2_cid_zero(&cid);
|
||||||
|
ngtcp2_dcid_init(dcid, 0, &cid, NULL);
|
||||||
|
ngtcp2_dcid_set_path(dcid, path);
|
||||||
|
|
||||||
|
return dcid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_bind_dcid(ngtcp2_dcidtr *dtr, ngtcp2_dcid **pdest,
|
||||||
|
const ngtcp2_path *path, ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_dcidtr_cb on_retire, void *user_data) {
|
||||||
|
const ngtcp2_dcid *src;
|
||||||
|
ngtcp2_dcid *dest;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (ngtcp2_ringbuf_full(&dtr->bound.rb)) {
|
||||||
|
rv = dcidtr_on_retire(dtr, ngtcp2_ringbuf_get(&dtr->bound.rb, 0), on_retire,
|
||||||
|
user_data);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
src = ngtcp2_ringbuf_get(&dtr->unused.rb, 0);
|
||||||
|
dest = ngtcp2_ringbuf_push_back(&dtr->bound.rb);
|
||||||
|
|
||||||
|
ngtcp2_dcid_copy(dest, src);
|
||||||
|
dest->bound_ts = ts;
|
||||||
|
ngtcp2_dcid_set_path(dest, path);
|
||||||
|
|
||||||
|
ngtcp2_ringbuf_pop_front(&dtr->unused.rb);
|
||||||
|
|
||||||
|
*pdest = dest;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int verify_stateless_reset(const ngtcp2_ringbuf *rb,
|
||||||
|
const ngtcp2_path *path,
|
||||||
|
const uint8_t *token) {
|
||||||
|
const ngtcp2_dcid *dcid;
|
||||||
|
size_t i, len = ngtcp2_ringbuf_len(rb);
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, i);
|
||||||
|
if (ngtcp2_dcid_verify_stateless_reset_token(dcid, path, token) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
const ngtcp2_dcid *dcid;
|
||||||
|
size_t i, len = ngtcp2_ringbuf_len(rb);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, i);
|
||||||
|
rv = ngtcp2_dcid_verify_uniqueness(dcid, seq, cid, token);
|
||||||
|
if (rv != 0) {
|
||||||
|
return NGTCP2_ERR_PROTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngtcp2_cid_eq(&dcid->cid, cid)) {
|
||||||
|
*pfound = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_verify_token_uniqueness(const ngtcp2_dcidtr *dtr, int *pfound,
|
||||||
|
uint64_t seq, const ngtcp2_cid *cid,
|
||||||
|
const uint8_t *token) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = verify_token_uniqueness(&dtr->bound.rb, pfound, seq, cid, token);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return verify_token_uniqueness(&dtr->unused.rb, pfound, seq, cid, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_dcid_at(ngtcp2_ringbuf *rb, size_t at) {
|
||||||
|
const ngtcp2_dcid *src;
|
||||||
|
ngtcp2_dcid *dest;
|
||||||
|
|
||||||
|
if (at == 0) {
|
||||||
|
ngtcp2_ringbuf_pop_front(rb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (at == ngtcp2_ringbuf_len(rb) - 1) {
|
||||||
|
ngtcp2_ringbuf_pop_back(rb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = ngtcp2_ringbuf_get(rb, ngtcp2_ringbuf_len(rb) - 1);
|
||||||
|
dest = ngtcp2_ringbuf_get(rb, at);
|
||||||
|
|
||||||
|
ngtcp2_dcid_copy(dest, src);
|
||||||
|
ngtcp2_ringbuf_pop_back(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dcidtr_retire_dcid_prior_to(ngtcp2_dcidtr *dtr, ngtcp2_ringbuf *rb,
|
||||||
|
uint64_t seq, ngtcp2_dcidtr_cb on_retire,
|
||||||
|
void *user_data) {
|
||||||
|
size_t i;
|
||||||
|
const ngtcp2_dcid *dcid;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
for (i = 0; i < ngtcp2_ringbuf_len(rb);) {
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, i);
|
||||||
|
if (dcid->seq >= seq) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = dcidtr_on_retire(dtr, dcid, on_retire, user_data);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_dcid_at(rb, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_retire_inactive_dcid_prior_to(ngtcp2_dcidtr *dtr,
|
||||||
|
uint64_t seq,
|
||||||
|
ngtcp2_dcidtr_cb on_retire,
|
||||||
|
void *user_data) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv =
|
||||||
|
dcidtr_retire_dcid_prior_to(dtr, &dtr->bound.rb, seq, on_retire, user_data);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dcidtr_retire_dcid_prior_to(dtr, &dtr->unused.rb, seq, on_retire,
|
||||||
|
user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_retire_active_dcid(ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_dcid *dcid, ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_dcidtr_cb on_deactivate,
|
||||||
|
void *user_data) {
|
||||||
|
ngtcp2_ringbuf *rb = &dtr->retired.rb;
|
||||||
|
const ngtcp2_dcid *stale_dcid;
|
||||||
|
ngtcp2_dcid *dest;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
assert(dcid->cid.datalen);
|
||||||
|
|
||||||
|
if (ngtcp2_ringbuf_full(rb)) {
|
||||||
|
stale_dcid = ngtcp2_ringbuf_get(rb, 0);
|
||||||
|
rv = on_deactivate(stale_dcid, user_data);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest = ngtcp2_ringbuf_push_back(rb);
|
||||||
|
ngtcp2_dcid_copy(dest, dcid);
|
||||||
|
dest->retired_ts = ts;
|
||||||
|
|
||||||
|
return dcidtr_on_retire(dtr, dest, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_remove_stale_retired_dcid(ngtcp2_dcidtr *dtr,
|
||||||
|
ngtcp2_duration timeout,
|
||||||
|
ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_dcidtr_cb on_deactivate,
|
||||||
|
void *user_data) {
|
||||||
|
ngtcp2_ringbuf *rb = &dtr->retired.rb;
|
||||||
|
const ngtcp2_dcid *dcid;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
for (; ngtcp2_ringbuf_len(rb);) {
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, 0);
|
||||||
|
if (ngtcp2_tstamp_not_elapsed(dcid->retired_ts, timeout, ts)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = on_deactivate(dcid, user_data);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngtcp2_ringbuf_pop_front(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_pop_bound_dcid(ngtcp2_dcidtr *dtr, ngtcp2_dcid *dest,
|
||||||
|
const ngtcp2_path *path) {
|
||||||
|
const ngtcp2_dcid *src;
|
||||||
|
ngtcp2_ringbuf *rb = &dtr->bound.rb;
|
||||||
|
size_t len = ngtcp2_ringbuf_len(rb);
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
src = ngtcp2_ringbuf_get(rb, i);
|
||||||
|
if (ngtcp2_path_eq(&src->ps.path, path)) {
|
||||||
|
ngtcp2_dcid_copy(dest, src);
|
||||||
|
remove_dcid_at(rb, i);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGTCP2_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_retire_stale_bound_dcid(ngtcp2_dcidtr *dtr,
|
||||||
|
ngtcp2_duration timeout,
|
||||||
|
ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_dcidtr_cb on_retire,
|
||||||
|
void *user_data) {
|
||||||
|
ngtcp2_ringbuf *rb = &dtr->bound.rb;
|
||||||
|
size_t i;
|
||||||
|
const ngtcp2_dcid *dcid;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
for (i = 0; i < ngtcp2_ringbuf_len(rb);) {
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, i);
|
||||||
|
|
||||||
|
assert(dcid->cid.datalen);
|
||||||
|
|
||||||
|
if (ngtcp2_tstamp_not_elapsed(dcid->bound_ts, timeout, ts)) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = dcidtr_on_retire(dtr, dcid, on_retire, user_data);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_dcid_at(rb, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngtcp2_tstamp ngtcp2_dcidtr_earliest_bound_ts(const ngtcp2_dcidtr *dtr) {
|
||||||
|
const ngtcp2_ringbuf *rb = &dtr->bound.rb;
|
||||||
|
size_t i, len = ngtcp2_ringbuf_len(rb);
|
||||||
|
ngtcp2_tstamp res = UINT64_MAX;
|
||||||
|
const ngtcp2_dcid *dcid;
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, i);
|
||||||
|
|
||||||
|
assert(dcid->cid.datalen);
|
||||||
|
assert(dcid->bound_ts != UINT64_MAX);
|
||||||
|
|
||||||
|
res = ngtcp2_min_uint64(res, dcid->bound_ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngtcp2_tstamp ngtcp2_dcidtr_earliest_retired_ts(const ngtcp2_dcidtr *dtr) {
|
||||||
|
const ngtcp2_ringbuf *rb = &dtr->retired.rb;
|
||||||
|
const ngtcp2_dcid *dcid;
|
||||||
|
|
||||||
|
if (ngtcp2_ringbuf_len(rb) == 0) {
|
||||||
|
return UINT64_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, 0);
|
||||||
|
|
||||||
|
return dcid->retired_ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngtcp2_dcidtr_push_unused(ngtcp2_dcidtr *dtr, uint64_t seq,
|
||||||
|
const ngtcp2_cid *cid, const uint8_t *token) {
|
||||||
|
ngtcp2_dcid *dcid = ngtcp2_ringbuf_push_back(&dtr->unused.rb);
|
||||||
|
|
||||||
|
ngtcp2_dcid_init(dcid, seq, cid, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngtcp2_dcidtr_pop_unused_cid_token(ngtcp2_dcidtr *dtr, ngtcp2_dcid *dest) {
|
||||||
|
ngtcp2_ringbuf *rb = &dtr->unused.rb;
|
||||||
|
const ngtcp2_dcid *src;
|
||||||
|
|
||||||
|
assert(ngtcp2_ringbuf_len(rb));
|
||||||
|
|
||||||
|
src = ngtcp2_ringbuf_get(rb, 0);
|
||||||
|
|
||||||
|
dest->flags = NGTCP2_DCID_FLAG_NONE;
|
||||||
|
ngtcp2_dcid_copy_cid_token(dest, src);
|
||||||
|
|
||||||
|
ngtcp2_ringbuf_pop_front(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngtcp2_dcidtr_pop_unused(ngtcp2_dcidtr *dtr, ngtcp2_dcid *dest) {
|
||||||
|
ngtcp2_ringbuf *rb = &dtr->unused.rb;
|
||||||
|
const ngtcp2_dcid *src;
|
||||||
|
|
||||||
|
assert(ngtcp2_ringbuf_len(rb));
|
||||||
|
|
||||||
|
src = ngtcp2_ringbuf_get(rb, 0);
|
||||||
|
|
||||||
|
ngtcp2_dcid_copy(dest, src);
|
||||||
|
|
||||||
|
ngtcp2_ringbuf_pop_front(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_check_path_retired(const ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_path *path) {
|
||||||
|
const ngtcp2_ringbuf *rb = &dtr->retired.rb;
|
||||||
|
size_t i, len = ngtcp2_ringbuf_len(rb);
|
||||||
|
const ngtcp2_dcid *dcid;
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
dcid = ngtcp2_ringbuf_get(rb, i);
|
||||||
|
if (ngtcp2_path_eq(&dcid->ps.path, path)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ngtcp2_dcidtr_unused_len(const ngtcp2_dcidtr *dtr) {
|
||||||
|
return ngtcp2_ringbuf_len(&dtr->unused.rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ngtcp2_dcidtr_bound_len(const ngtcp2_dcidtr *dtr) {
|
||||||
|
return ngtcp2_ringbuf_len(&dtr->bound.rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ngtcp2_dcidtr_retired_len(const ngtcp2_dcidtr *dtr) {
|
||||||
|
return ngtcp2_ringbuf_len(&dtr->retired.rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ngtcp2_dcidtr_inactive_len(const ngtcp2_dcidtr *dtr) {
|
||||||
|
return ngtcp2_ringbuf_len(&dtr->unused.rb) +
|
||||||
|
ngtcp2_ringbuf_len(&dtr->bound.rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_unused_full(const ngtcp2_dcidtr *dtr) {
|
||||||
|
return ngtcp2_ringbuf_full(&dtr->unused.rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_unused_empty(const ngtcp2_dcidtr *dtr) {
|
||||||
|
return ngtcp2_ringbuf_len(&dtr->unused.rb) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ngtcp2_dcidtr_bound_full(const ngtcp2_dcidtr *dtr) {
|
||||||
|
return ngtcp2_ringbuf_full(&dtr->bound.rb);
|
||||||
|
}
|
||||||
343
deps/ngtcp2/ngtcp2/lib/ngtcp2_dcidtr.h
vendored
Normal file
343
deps/ngtcp2/ngtcp2/lib/ngtcp2_dcidtr.h
vendored
Normal file
|
|
@ -0,0 +1,343 @@
|
||||||
|
/*
|
||||||
|
* 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_DCIDTR_H
|
||||||
|
#define NGTCP2_DCIDTR_H
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
|
#include <ngtcp2/ngtcp2.h>
|
||||||
|
|
||||||
|
#include "ngtcp2_cid.h"
|
||||||
|
#include "ngtcp2_ringbuf.h"
|
||||||
|
|
||||||
|
/* NGTCP2_DCIDTR_MAX_BOUND_DCID_SIZE is the maximum number of
|
||||||
|
Destination Connection ID which has been bound to a particular
|
||||||
|
path, but not yet used as primary path, and path validation is not
|
||||||
|
performed from the local endpoint. It must be the power of 2. */
|
||||||
|
#define NGTCP2_DCIDTR_MAX_BOUND_DCID_SIZE 4
|
||||||
|
/* NGTCP2_DCIDTR_MAX_UNUSED_DCID_SIZE is the maximum number of
|
||||||
|
Destination Connection ID the remote endpoint provides to store.
|
||||||
|
It must be the power of 2. */
|
||||||
|
#define NGTCP2_DCIDTR_MAX_UNUSED_DCID_SIZE 8
|
||||||
|
/* NGTCP2_DCIDTR_MAX_RETIRED_DCID_SIZE is the maximum number of
|
||||||
|
retired Destination Connection ID kept to catch in-flight packet on
|
||||||
|
a retired path. It must be the power of 2. */
|
||||||
|
#define NGTCP2_DCIDTR_MAX_RETIRED_DCID_SIZE 2
|
||||||
|
|
||||||
|
ngtcp2_static_ringbuf_def(dcid_bound, NGTCP2_DCIDTR_MAX_BOUND_DCID_SIZE,
|
||||||
|
sizeof(ngtcp2_dcid))
|
||||||
|
ngtcp2_static_ringbuf_def(dcid_unused, NGTCP2_DCIDTR_MAX_UNUSED_DCID_SIZE,
|
||||||
|
sizeof(ngtcp2_dcid))
|
||||||
|
ngtcp2_static_ringbuf_def(dcid_retired, NGTCP2_DCIDTR_MAX_RETIRED_DCID_SIZE,
|
||||||
|
sizeof(ngtcp2_dcid))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr stores unused, bound, and retired Destination
|
||||||
|
* Connection IDs.
|
||||||
|
*/
|
||||||
|
typedef struct ngtcp2_dcidtr {
|
||||||
|
/* unused is a set of unused Destination Connection ID received from
|
||||||
|
a remote endpoint. They are considered inactive. */
|
||||||
|
ngtcp2_static_ringbuf_dcid_unused unused;
|
||||||
|
/* bound is a set of Destination Connection IDs which are bound to
|
||||||
|
particular paths. These paths are not validated yet. They are
|
||||||
|
considered inactive. */
|
||||||
|
ngtcp2_static_ringbuf_dcid_bound bound;
|
||||||
|
/* retired is a set of Destination Connection ID retired by local
|
||||||
|
endpoint. Keep them in 3*PTO to catch packets in flight along
|
||||||
|
the old path. They are considered active. */
|
||||||
|
ngtcp2_static_ringbuf_dcid_retired retired;
|
||||||
|
struct {
|
||||||
|
/* seqs contains sequence number of Destination Connection ID
|
||||||
|
whose retirement is not acknowledged by the remote endpoint
|
||||||
|
yet. */
|
||||||
|
uint64_t seqs[NGTCP2_DCIDTR_MAX_UNUSED_DCID_SIZE * 2];
|
||||||
|
/* len is the number of sequence numbers that seq contains. */
|
||||||
|
size_t len;
|
||||||
|
} retire_unacked;
|
||||||
|
} ngtcp2_dcidtr;
|
||||||
|
|
||||||
|
typedef int (*ngtcp2_dcidtr_cb)(const ngtcp2_dcid *dcid, void *user_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_init initializes |dtr|.
|
||||||
|
*/
|
||||||
|
void ngtcp2_dcidtr_init(ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_track_retired_seq tracks the sequence number |seq| of
|
||||||
|
* unacknowledged retiring Destination Connection ID.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGTCP2_ERR_CONNECTION_ID_LIMIT
|
||||||
|
* The number of unacknowledged retirement exceeds the limit.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_track_retired_seq(ngtcp2_dcidtr *dtr, uint64_t seq);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_untrack_retired_seq deletes the sequence number |seq|
|
||||||
|
* of unacknowledged retiring Destination Connection ID. It is fine
|
||||||
|
* if such sequence number is not found.
|
||||||
|
*/
|
||||||
|
void ngtcp2_dcidtr_untrack_retired_seq(ngtcp2_dcidtr *dtr, uint64_t seq);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_check_retired_seq_tracked returns nonzero if |seq|
|
||||||
|
* has already been tracked.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_check_retired_seq_tracked(const ngtcp2_dcidtr *dtr,
|
||||||
|
uint64_t seq);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_find_bound_dcid returns the pointer to ngtcp2_dcid
|
||||||
|
* that bound to |path|. It returns NULL if there is no such
|
||||||
|
* ngtcp2_dcid.
|
||||||
|
*/
|
||||||
|
ngtcp2_dcid *ngtcp2_dcidtr_find_bound_dcid(const ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_path *path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_bind_zerolen_dcid binds zero-length Destination
|
||||||
|
* Connection ID to |path|, and returns the pointer to the bound
|
||||||
|
* ngtcp2_dcid.
|
||||||
|
*/
|
||||||
|
ngtcp2_dcid *ngtcp2_dcidtr_bind_zerolen_dcid(ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_path *path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_bind_dcid binds non-zero Destination Connection ID to
|
||||||
|
* |path|. |ts| is the current timestamp. The buffer space of bound
|
||||||
|
* Destination Connection ID is limited. If it is full, the earliest
|
||||||
|
* one is removed. |on_retire|, if specified, is called for the
|
||||||
|
* removed ngtcp2_dcid with |user_data|. This function assigns the
|
||||||
|
* pointer to bound ngtcp2_dcid to |*pdest|.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or negative error code that
|
||||||
|
* |on_retire| returns.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_bind_dcid(ngtcp2_dcidtr *dtr, ngtcp2_dcid **pdest,
|
||||||
|
const ngtcp2_path *path, ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_dcidtr_cb on_retire, void *user_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_verify_stateless_reset verifies the stateless reset
|
||||||
|
* token |token| received from |path|. It returns 0 if it succeeds,
|
||||||
|
* or one of the following negative error codes:
|
||||||
|
*
|
||||||
|
* NGTCP2_ERR_INVALID_ARGUMENT
|
||||||
|
* There is no Destination Connection ID that matches the given
|
||||||
|
* |path| and |token|.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_verify_stateless_reset(const ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_path *path,
|
||||||
|
const uint8_t *token);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_verify_token_uniqueness verifies that the uniqueness
|
||||||
|
* of the combination of |seq|, |cid|, and |token| against the exiting
|
||||||
|
* Destination Connection IDs. That is:
|
||||||
|
*
|
||||||
|
* - If they do not share the same seq, then their Connection IDs must
|
||||||
|
* be different.
|
||||||
|
*
|
||||||
|
* - If they share the same seq, then their Connection IDs and tokens
|
||||||
|
* must be the same.
|
||||||
|
*
|
||||||
|
* If this function succeeds, and there is Destination Connection ID
|
||||||
|
* which shares |seq|, |cid|, and |token|, |*pfound| is set to
|
||||||
|
* nonzero.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGTCP2_ERR_PROTO
|
||||||
|
* The given combination of values does not satisfy the above
|
||||||
|
* conditions.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_verify_token_uniqueness(const ngtcp2_dcidtr *dtr, int *pfound,
|
||||||
|
uint64_t seq, const ngtcp2_cid *cid,
|
||||||
|
const uint8_t *token);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_retire_inactive_dcid_prior_to retires inactive
|
||||||
|
* Destination Connection IDs (unused or bound) whose seq is less than
|
||||||
|
* |seq|. For each retired ngtcp2_dcid, |on_retire|, if specified, is
|
||||||
|
* called with |user_data|.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or negative error code that
|
||||||
|
* |on_retire| returns.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_retire_inactive_dcid_prior_to(ngtcp2_dcidtr *dtr,
|
||||||
|
uint64_t seq,
|
||||||
|
ngtcp2_dcidtr_cb on_retire,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_retire_active_dcid adds an active |dcid| to the
|
||||||
|
* retired Destination Connection ID buffer. The buffer space of
|
||||||
|
* retired Destination Connection ID is limited. If it is full, the
|
||||||
|
* earliest one is removed. |on_deactivate| is called for the removed
|
||||||
|
* ngtcp2_dcid with |user_data|.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or negative error code that
|
||||||
|
* |on_deactivate| returns.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_retire_active_dcid(ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_dcid *dcid, ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_dcidtr_cb on_deactivate,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_retire_stale_bound_dcid retires stale bound
|
||||||
|
* Destination Connection ID. For each retired ngtcp2_dcid,
|
||||||
|
* |on_retire|, if specified, is called with |user_data|.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_retire_stale_bound_dcid(ngtcp2_dcidtr *dtr,
|
||||||
|
ngtcp2_duration timeout,
|
||||||
|
ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_dcidtr_cb on_retire,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_remove_stale_retired_dcid removes stale retired
|
||||||
|
* Destination Connection ID. For each removed ngtcp2_dcid,
|
||||||
|
* |on_deactivate| is called with |user_data|.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or negative error code that
|
||||||
|
* |on_deactivate| returns.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_remove_stale_retired_dcid(ngtcp2_dcidtr *dtr,
|
||||||
|
ngtcp2_duration timeout,
|
||||||
|
ngtcp2_tstamp ts,
|
||||||
|
ngtcp2_dcidtr_cb on_deactivate,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_pop_bound_dcid removes Destination Connection ID that
|
||||||
|
* is bound to |path|, and copies it into the object pointed by
|
||||||
|
* |dest|.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGTCP2_ERR_INVALID_ARGUMENT
|
||||||
|
* No ngtcp2_dcid bound to |path| found.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_pop_bound_dcid(ngtcp2_dcidtr *dtr, ngtcp2_dcid *dest,
|
||||||
|
const ngtcp2_path *path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_earliest_bound_ts returns earliest timestamp when a
|
||||||
|
* Destination Connection ID is bound. If there is no bound
|
||||||
|
* Destination Connection ID, this function returns UINT64_MAX.
|
||||||
|
*/
|
||||||
|
ngtcp2_tstamp ngtcp2_dcidtr_earliest_bound_ts(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_earliest_retired_ts returns earliest timestamp when a
|
||||||
|
* Destination Connection ID is retired. If there is no retired
|
||||||
|
* Destination Connection ID, this function returns UINT64_MAX.
|
||||||
|
*/
|
||||||
|
ngtcp2_tstamp ngtcp2_dcidtr_earliest_retired_ts(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_push_unused adds new Destination Connection ID to the
|
||||||
|
* unused buffer. |seq| is its sequence number, |cid| is its
|
||||||
|
* Connection ID, and |token| is its stateless reset token. If the
|
||||||
|
* buffer space is full, the earliest ngtcp2_dcid is removed.
|
||||||
|
*/
|
||||||
|
void ngtcp2_dcidtr_push_unused(ngtcp2_dcidtr *dtr, uint64_t seq,
|
||||||
|
const ngtcp2_cid *cid, const uint8_t *token);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_pop_unused_cid_token removes an unused Destination
|
||||||
|
* Connection ID, and copies it into the object pointed by |dcid| with
|
||||||
|
* ngtcp2_dcid_copy_cid_token. This function assumes that there is at
|
||||||
|
* least one unused Destination Connection ID.
|
||||||
|
*/
|
||||||
|
void ngtcp2_dcidtr_pop_unused_cid_token(ngtcp2_dcidtr *dtr, ngtcp2_dcid *dcid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_pop_unused removes an unused Destination Connection
|
||||||
|
* ID, and copies it into the object pointed by |dcid| with
|
||||||
|
* ngtcp2_dcid_copy. This function assumes that there is at least one
|
||||||
|
* unused Destination Connection ID.
|
||||||
|
*/
|
||||||
|
void ngtcp2_dcidtr_pop_unused(ngtcp2_dcidtr *dtr, ngtcp2_dcid *dcid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_check_path_retired returns nonzero if |path| is
|
||||||
|
* included in retired Destination Connection IDs.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_check_path_retired(const ngtcp2_dcidtr *dtr,
|
||||||
|
const ngtcp2_path *path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_unused_len returns the number of unused Destination
|
||||||
|
* Connection ID.
|
||||||
|
*/
|
||||||
|
size_t ngtcp2_dcidtr_unused_len(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_bound_len returns the number of bound Destination
|
||||||
|
* Connection ID.
|
||||||
|
*/
|
||||||
|
size_t ngtcp2_dcidtr_bound_len(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_retired_len returns the number of retired Destination
|
||||||
|
* Connection ID.
|
||||||
|
*/
|
||||||
|
size_t ngtcp2_dcidtr_retired_len(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_inactive_len returns the number of unused and bound
|
||||||
|
* Destination Connection ID.
|
||||||
|
*/
|
||||||
|
size_t ngtcp2_dcidtr_inactive_len(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_unused_full returns nonzero if the buffer of unused
|
||||||
|
* Destination Connection ID is full.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_unused_full(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_unused_empty returns nonzero if the buffer of unused
|
||||||
|
* Destination Connection ID is empty.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_unused_empty(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_dcidtr_bound_full returns nonzero if the buffer of bound
|
||||||
|
* Destination Connection ID is full.
|
||||||
|
*/
|
||||||
|
int ngtcp2_dcidtr_bound_full(const ngtcp2_dcidtr *dtr);
|
||||||
|
|
||||||
|
#endif /* NGTCP2_DCIDTR_H */
|
||||||
20
deps/ngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c
vendored
20
deps/ngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c
vendored
|
|
@ -29,17 +29,6 @@
|
||||||
|
|
||||||
ngtcp2_objalloc_def(frame_chain, ngtcp2_frame_chain, oplent)
|
ngtcp2_objalloc_def(frame_chain, ngtcp2_frame_chain, oplent)
|
||||||
|
|
||||||
int ngtcp2_frame_chain_new(ngtcp2_frame_chain **pfrc, const ngtcp2_mem *mem) {
|
|
||||||
*pfrc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_frame_chain));
|
|
||||||
if (*pfrc == NULL) {
|
|
||||||
return NGTCP2_ERR_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngtcp2_frame_chain_init(*pfrc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc,
|
int ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc,
|
||||||
ngtcp2_objalloc *objalloc) {
|
ngtcp2_objalloc *objalloc) {
|
||||||
*pfrc = ngtcp2_objalloc_frame_chain_get(objalloc);
|
*pfrc = ngtcp2_objalloc_frame_chain_get(objalloc);
|
||||||
|
|
@ -83,13 +72,13 @@ int ngtcp2_frame_chain_new_token_objalloc_new(ngtcp2_frame_chain **pfrc,
|
||||||
size_t tokenlen,
|
size_t tokenlen,
|
||||||
ngtcp2_objalloc *objalloc,
|
ngtcp2_objalloc *objalloc,
|
||||||
const ngtcp2_mem *mem) {
|
const ngtcp2_mem *mem) {
|
||||||
size_t avail = sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token);
|
|
||||||
int rv;
|
int rv;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
ngtcp2_frame *fr;
|
ngtcp2_frame *fr;
|
||||||
|
|
||||||
if (tokenlen > avail) {
|
if (tokenlen > NGTCP2_FRAME_CHAIN_NEW_TOKEN_THRES) {
|
||||||
rv = ngtcp2_frame_chain_extralen_new(pfrc, tokenlen - avail, mem);
|
rv = ngtcp2_frame_chain_extralen_new(
|
||||||
|
pfrc, tokenlen - NGTCP2_FRAME_CHAIN_NEW_TOKEN_THRES, mem);
|
||||||
} else {
|
} else {
|
||||||
rv = ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
|
rv = ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
|
||||||
}
|
}
|
||||||
|
|
@ -144,8 +133,7 @@ void ngtcp2_frame_chain_objalloc_del(ngtcp2_frame_chain *frc,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NGTCP2_FRAME_NEW_TOKEN:
|
case NGTCP2_FRAME_NEW_TOKEN:
|
||||||
if (frc->fr.new_token.tokenlen >
|
if (frc->fr.new_token.tokenlen > NGTCP2_FRAME_CHAIN_NEW_TOKEN_THRES) {
|
||||||
sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token)) {
|
|
||||||
ngtcp2_frame_chain_del(frc, mem);
|
ngtcp2_frame_chain_del(frc, mem);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
44
deps/ngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h
vendored
44
deps/ngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h
vendored
|
|
@ -95,28 +95,15 @@ int ngtcp2_bind_frame_chains(ngtcp2_frame_chain *a, ngtcp2_frame_chain *b,
|
||||||
#define NGTCP2_MAX_STREAM_DATACNT 256
|
#define NGTCP2_MAX_STREAM_DATACNT 256
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_frame_chain_new allocates ngtcp2_frame_chain object and
|
* ngtcp2_frame_chain_objalloc_new allocates ngtcp2_frame_chain using
|
||||||
* assigns its pointer to |*pfrc|.
|
* |objalloc|.
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGTCP2_ERR_NOMEM
|
|
||||||
* Out of memory.
|
|
||||||
*/
|
|
||||||
int ngtcp2_frame_chain_new(ngtcp2_frame_chain **pfrc, const ngtcp2_mem *mem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ngtcp2_frame_chain_objalloc_new behaves like
|
|
||||||
* ngtcp2_frame_chain_new, but it uses |objalloc| to allocate the object.
|
|
||||||
*/
|
*/
|
||||||
int ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc,
|
int ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc,
|
||||||
ngtcp2_objalloc *objalloc);
|
ngtcp2_objalloc *objalloc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_frame_chain_extralen_new works like ngtcp2_frame_chain_new,
|
* ngtcp2_frame_chain_extralen_new allocates ngtcp2_frame_chain
|
||||||
* but it allocates extra memory |extralen| in order to extend
|
* followed by |extralen| bytes.
|
||||||
* ngtcp2_frame.
|
|
||||||
*/
|
*/
|
||||||
int ngtcp2_frame_chain_extralen_new(ngtcp2_frame_chain **pfrc, size_t extralen,
|
int ngtcp2_frame_chain_extralen_new(ngtcp2_frame_chain **pfrc, size_t extralen,
|
||||||
const ngtcp2_mem *mem);
|
const ngtcp2_mem *mem);
|
||||||
|
|
@ -134,12 +121,18 @@ int ngtcp2_frame_chain_extralen_new(ngtcp2_frame_chain **pfrc, size_t extralen,
|
||||||
#define NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES \
|
#define NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES \
|
||||||
(NGTCP2_FRAME_CHAIN_STREAM_AVAIL / sizeof(ngtcp2_vec) + 1)
|
(NGTCP2_FRAME_CHAIN_STREAM_AVAIL / sizeof(ngtcp2_vec) + 1)
|
||||||
|
|
||||||
|
/* NGTCP2_FRAME_CHAIN_NEW_TOKEN_THRES is the length of a token that
|
||||||
|
changes allocation method. If the length is more than this value,
|
||||||
|
ngtcp2_frame_chain is allocated without ngtcp2_objalloc.
|
||||||
|
Otherwise, it is allocated using ngtcp2_objalloc. */
|
||||||
|
#define NGTCP2_FRAME_CHAIN_NEW_TOKEN_THRES \
|
||||||
|
(sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_frame_chain_stream_datacnt_objalloc_new works like
|
* ngtcp2_frame_chain_stream_datacnt_objalloc_new allocates enough
|
||||||
* ngtcp2_frame_chain_new, but it allocates enough data to store
|
* data to store additional |datacnt| - 1 ngtcp2_vec object after
|
||||||
* additional |datacnt| - 1 ngtcp2_vec object after ngtcp2_stream
|
* ngtcp2_stream object. If no additional space is required, in other
|
||||||
* object. If no additional space is required, in other words,
|
* words, |datacnt| <= NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES,
|
||||||
* |datacnt| <= NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES,
|
|
||||||
* ngtcp2_frame_chain_objalloc_new is called internally. Otherwise,
|
* ngtcp2_frame_chain_objalloc_new is called internally. Otherwise,
|
||||||
* ngtcp2_frame_chain_extralen_new is used and objalloc is not used.
|
* ngtcp2_frame_chain_extralen_new is used and objalloc is not used.
|
||||||
* Therefore, it is important to call ngtcp2_frame_chain_objalloc_del
|
* Therefore, it is important to call ngtcp2_frame_chain_objalloc_del
|
||||||
|
|
@ -150,6 +143,13 @@ int ngtcp2_frame_chain_stream_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc,
|
||||||
ngtcp2_objalloc *objalloc,
|
ngtcp2_objalloc *objalloc,
|
||||||
const ngtcp2_mem *mem);
|
const ngtcp2_mem *mem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_frame_chain_new_token_objalloc_new allocates enough space to
|
||||||
|
* store the given token. If |tokenlen| <=
|
||||||
|
* NGTCP2_FRAME_CHAIN_NEW_TOKEN_THRES, ngtcp2_frame_chain_objalloc_new
|
||||||
|
* is called internally. Otherwise, ngtcp2_frame_chain_extralen_new
|
||||||
|
* is used, and objalloc is not used.
|
||||||
|
*/
|
||||||
int ngtcp2_frame_chain_new_token_objalloc_new(ngtcp2_frame_chain **pfrc,
|
int ngtcp2_frame_chain_new_token_objalloc_new(ngtcp2_frame_chain **pfrc,
|
||||||
const uint8_t *token,
|
const uint8_t *token,
|
||||||
size_t tokenlen,
|
size_t tokenlen,
|
||||||
|
|
|
||||||
27
deps/ngtcp2/ngtcp2/lib/ngtcp2_gaptr.c
vendored
27
deps/ngtcp2/ngtcp2/lib/ngtcp2_gaptr.c
vendored
|
|
@ -35,7 +35,9 @@ void ngtcp2_gaptr_init(ngtcp2_gaptr *gaptr, const ngtcp2_mem *mem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gaptr_gap_init(ngtcp2_gaptr *gaptr) {
|
static int gaptr_gap_init(ngtcp2_gaptr *gaptr) {
|
||||||
ngtcp2_range range = {0, UINT64_MAX};
|
ngtcp2_range range = {
|
||||||
|
.end = UINT64_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
return ngtcp2_ksl_insert(&gaptr->gap, NULL, &range, NULL);
|
return ngtcp2_ksl_insert(&gaptr->gap, NULL, &range, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +52,11 @@ void ngtcp2_gaptr_free(ngtcp2_gaptr *gaptr) {
|
||||||
|
|
||||||
int ngtcp2_gaptr_push(ngtcp2_gaptr *gaptr, uint64_t offset, uint64_t datalen) {
|
int ngtcp2_gaptr_push(ngtcp2_gaptr *gaptr, uint64_t offset, uint64_t datalen) {
|
||||||
int rv;
|
int rv;
|
||||||
ngtcp2_range k, m, l, r, q = {offset, offset + datalen};
|
ngtcp2_range k, m, l, r;
|
||||||
|
ngtcp2_range q = {
|
||||||
|
.begin = offset,
|
||||||
|
.end = offset + datalen,
|
||||||
|
};
|
||||||
ngtcp2_ksl_it it;
|
ngtcp2_ksl_it it;
|
||||||
|
|
||||||
if (ngtcp2_ksl_len(&gaptr->gap) == 0) {
|
if (ngtcp2_ksl_len(&gaptr->gap) == 0) {
|
||||||
|
|
@ -110,11 +116,16 @@ uint64_t ngtcp2_gaptr_first_gap_offset(const ngtcp2_gaptr *gaptr) {
|
||||||
|
|
||||||
ngtcp2_range ngtcp2_gaptr_get_first_gap_after(const ngtcp2_gaptr *gaptr,
|
ngtcp2_range ngtcp2_gaptr_get_first_gap_after(const ngtcp2_gaptr *gaptr,
|
||||||
uint64_t offset) {
|
uint64_t offset) {
|
||||||
ngtcp2_range q = {offset, offset + 1};
|
ngtcp2_range q = {
|
||||||
|
.begin = offset,
|
||||||
|
.end = offset + 1,
|
||||||
|
};
|
||||||
ngtcp2_ksl_it it;
|
ngtcp2_ksl_it it;
|
||||||
|
|
||||||
if (ngtcp2_ksl_len(&gaptr->gap) == 0) {
|
if (ngtcp2_ksl_len(&gaptr->gap) == 0) {
|
||||||
ngtcp2_range r = {0, UINT64_MAX};
|
ngtcp2_range r = {
|
||||||
|
.end = UINT64_MAX,
|
||||||
|
};
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,7 +139,10 @@ ngtcp2_range ngtcp2_gaptr_get_first_gap_after(const ngtcp2_gaptr *gaptr,
|
||||||
|
|
||||||
int ngtcp2_gaptr_is_pushed(const ngtcp2_gaptr *gaptr, uint64_t offset,
|
int ngtcp2_gaptr_is_pushed(const ngtcp2_gaptr *gaptr, uint64_t offset,
|
||||||
uint64_t datalen) {
|
uint64_t datalen) {
|
||||||
ngtcp2_range q = {offset, offset + datalen};
|
ngtcp2_range q = {
|
||||||
|
.begin = offset,
|
||||||
|
.end = offset + datalen,
|
||||||
|
};
|
||||||
ngtcp2_ksl_it it;
|
ngtcp2_ksl_it it;
|
||||||
ngtcp2_range m;
|
ngtcp2_range m;
|
||||||
|
|
||||||
|
|
@ -138,6 +152,9 @@ int ngtcp2_gaptr_is_pushed(const ngtcp2_gaptr *gaptr, uint64_t offset,
|
||||||
|
|
||||||
it = ngtcp2_ksl_lower_bound_search(&gaptr->gap, &q,
|
it = ngtcp2_ksl_lower_bound_search(&gaptr->gap, &q,
|
||||||
ngtcp2_ksl_range_exclusive_search);
|
ngtcp2_ksl_range_exclusive_search);
|
||||||
|
|
||||||
|
assert(!ngtcp2_ksl_it_end(&it));
|
||||||
|
|
||||||
m = ngtcp2_range_intersect(&q, (ngtcp2_range *)ngtcp2_ksl_it_key(&it));
|
m = ngtcp2_range_intersect(&q, (ngtcp2_range *)ngtcp2_ksl_it_key(&it));
|
||||||
|
|
||||||
return ngtcp2_range_len(&m) == 0;
|
return ngtcp2_range_len(&m) == 0;
|
||||||
|
|
|
||||||
2
deps/ngtcp2/ngtcp2/lib/ngtcp2_ksl.c
vendored
2
deps/ngtcp2/ngtcp2/lib/ngtcp2_ksl.c
vendored
|
|
@ -33,7 +33,7 @@
|
||||||
#include "ngtcp2_mem.h"
|
#include "ngtcp2_mem.h"
|
||||||
#include "ngtcp2_range.h"
|
#include "ngtcp2_range.h"
|
||||||
|
|
||||||
static ngtcp2_ksl_blk null_blk = {{{NULL, NULL, 0, 0, {0}}}};
|
static ngtcp2_ksl_blk null_blk;
|
||||||
|
|
||||||
ngtcp2_objalloc_def(ksl_blk, ngtcp2_ksl_blk, oplent)
|
ngtcp2_objalloc_def(ksl_blk, ngtcp2_ksl_blk, oplent)
|
||||||
|
|
||||||
|
|
|
||||||
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_map.c
vendored
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_map.c
vendored
|
|
@ -119,7 +119,11 @@ void ngtcp2_map_print_distance(const ngtcp2_map *map) {
|
||||||
static int insert(ngtcp2_map_bucket *table, size_t hashbits,
|
static int insert(ngtcp2_map_bucket *table, size_t hashbits,
|
||||||
ngtcp2_map_key_type key, void *data) {
|
ngtcp2_map_key_type key, void *data) {
|
||||||
size_t idx = hash(key, hashbits);
|
size_t idx = hash(key, hashbits);
|
||||||
ngtcp2_map_bucket b = {0, key, data}, *bkt;
|
ngtcp2_map_bucket b = {
|
||||||
|
.key = key,
|
||||||
|
.data = data,
|
||||||
|
};
|
||||||
|
ngtcp2_map_bucket *bkt;
|
||||||
size_t mask = (1u << hashbits) - 1;
|
size_t mask = (1u << hashbits) - 1;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
|
||||||
8
deps/ngtcp2/ngtcp2/lib/ngtcp2_mem.c
vendored
8
deps/ngtcp2/ngtcp2/lib/ngtcp2_mem.c
vendored
|
|
@ -51,8 +51,12 @@ static void *default_realloc(void *ptr, size_t size, void *user_data) {
|
||||||
return realloc(ptr, size);
|
return realloc(ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ngtcp2_mem mem_default = {NULL, default_malloc, default_free,
|
static const ngtcp2_mem mem_default = {
|
||||||
default_calloc, default_realloc};
|
.malloc = default_malloc,
|
||||||
|
.free = default_free,
|
||||||
|
.calloc = default_calloc,
|
||||||
|
.realloc = default_realloc,
|
||||||
|
};
|
||||||
|
|
||||||
const ngtcp2_mem *ngtcp2_mem_default(void) { return &mem_default; }
|
const ngtcp2_mem *ngtcp2_mem_default(void) { return &mem_default; }
|
||||||
|
|
||||||
|
|
|
||||||
8
deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c
vendored
8
deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c
vendored
|
|
@ -145,8 +145,7 @@ int ngtcp2_pkt_decode_version_cid(ngtcp2_version_cid *dest, const uint8_t *data,
|
||||||
|
|
||||||
void ngtcp2_pkt_hd_init(ngtcp2_pkt_hd *hd, uint8_t flags, uint8_t type,
|
void ngtcp2_pkt_hd_init(ngtcp2_pkt_hd *hd, uint8_t flags, uint8_t type,
|
||||||
const ngtcp2_cid *dcid, const ngtcp2_cid *scid,
|
const ngtcp2_cid *dcid, const ngtcp2_cid *scid,
|
||||||
int64_t pkt_num, size_t pkt_numlen, uint32_t version,
|
int64_t pkt_num, size_t pkt_numlen, uint32_t version) {
|
||||||
size_t len) {
|
|
||||||
hd->flags = flags;
|
hd->flags = flags;
|
||||||
hd->type = type;
|
hd->type = type;
|
||||||
|
|
||||||
|
|
@ -167,7 +166,7 @@ void ngtcp2_pkt_hd_init(ngtcp2_pkt_hd *hd, uint8_t flags, uint8_t type,
|
||||||
hd->tokenlen = 0;
|
hd->tokenlen = 0;
|
||||||
hd->pkt_numlen = pkt_numlen;
|
hd->pkt_numlen = pkt_numlen;
|
||||||
hd->version = version;
|
hd->version = version;
|
||||||
hd->len = len;
|
hd->len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngtcp2_ssize ngtcp2_pkt_decode_hd_long(ngtcp2_pkt_hd *dest, const uint8_t *pkt,
|
ngtcp2_ssize ngtcp2_pkt_decode_hd_long(ngtcp2_pkt_hd *dest, const uint8_t *pkt,
|
||||||
|
|
@ -2285,8 +2284,7 @@ ngtcp2_ssize ngtcp2_pkt_write_retry(
|
||||||
}
|
}
|
||||||
|
|
||||||
ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_LONG_FORM, NGTCP2_PKT_RETRY, dcid,
|
ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_LONG_FORM, NGTCP2_PKT_RETRY, dcid,
|
||||||
scid, /* pkt_num = */ 0, /* pkt_numlen = */ 1, version,
|
scid, /* pkt_num = */ 0, /* pkt_numlen = */ 1, version);
|
||||||
/* len = */ 0);
|
|
||||||
|
|
||||||
pseudo_retrylen =
|
pseudo_retrylen =
|
||||||
ngtcp2_pkt_encode_pseudo_retry(pseudo_retry, sizeof(pseudo_retry), &hd,
|
ngtcp2_pkt_encode_pseudo_retry(pseudo_retry, sizeof(pseudo_retry), &hd,
|
||||||
|
|
|
||||||
10
deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h
vendored
10
deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h
vendored
|
|
@ -57,6 +57,10 @@
|
||||||
#define NGTCP2_STREAM_LEN_BIT 0x02
|
#define NGTCP2_STREAM_LEN_BIT 0x02
|
||||||
#define NGTCP2_STREAM_OFF_BIT 0x04
|
#define NGTCP2_STREAM_OFF_BIT 0x04
|
||||||
|
|
||||||
|
/* NGTCP2_MIN_QUIC_PKTLEN is the minimum length of a valid QUIC
|
||||||
|
packet. */
|
||||||
|
#define NGTCP2_MIN_QUIC_PKTLEN 21
|
||||||
|
|
||||||
/* NGTCP2_STREAM_OVERHEAD is the maximum number of bytes required
|
/* NGTCP2_STREAM_OVERHEAD is the maximum number of bytes required
|
||||||
other than payload for STREAM frame. That is from type field to
|
other than payload for STREAM frame. That is from type field to
|
||||||
the beginning of the payload. */
|
the beginning of the payload. */
|
||||||
|
|
@ -407,13 +411,11 @@ void ngtcp2_pkt_chain_del(ngtcp2_pkt_chain *pc, const ngtcp2_mem *mem);
|
||||||
* |dcid| and/or |scid| is NULL, Destination Connection ID and/or
|
* |dcid| and/or |scid| is NULL, Destination Connection ID and/or
|
||||||
* Source Connection ID of |hd| is empty respectively. |pkt_numlen|
|
* Source Connection ID of |hd| is empty respectively. |pkt_numlen|
|
||||||
* is the number of bytes used to encode |pkt_num| and either 1, 2, or
|
* is the number of bytes used to encode |pkt_num| and either 1, 2, or
|
||||||
* 4. |version| is QUIC version for long header. |len| is the length
|
* 4. |version| is QUIC version for long header.
|
||||||
* field of Initial, 0RTT, and Handshake packets.
|
|
||||||
*/
|
*/
|
||||||
void ngtcp2_pkt_hd_init(ngtcp2_pkt_hd *hd, uint8_t flags, uint8_t type,
|
void ngtcp2_pkt_hd_init(ngtcp2_pkt_hd *hd, uint8_t flags, uint8_t type,
|
||||||
const ngtcp2_cid *dcid, const ngtcp2_cid *scid,
|
const ngtcp2_cid *dcid, const ngtcp2_cid *scid,
|
||||||
int64_t pkt_num, size_t pkt_numlen, uint32_t version,
|
int64_t pkt_num, size_t pkt_numlen, uint32_t version);
|
||||||
size_t len);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_pkt_encode_hd_long encodes |hd| as QUIC long header into
|
* ngtcp2_pkt_encode_hd_long encodes |hd| as QUIC long header into
|
||||||
|
|
|
||||||
16
deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.c
vendored
16
deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.c
vendored
|
|
@ -161,19 +161,3 @@ void ngtcp2_pq_remove(ngtcp2_pq *pq, ngtcp2_pq_entry *item) {
|
||||||
int ngtcp2_pq_empty(const ngtcp2_pq *pq) { return pq->length == 0; }
|
int ngtcp2_pq_empty(const ngtcp2_pq *pq) { return pq->length == 0; }
|
||||||
|
|
||||||
size_t ngtcp2_pq_size(const ngtcp2_pq *pq) { return pq->length; }
|
size_t ngtcp2_pq_size(const ngtcp2_pq *pq) { return pq->length; }
|
||||||
|
|
||||||
int ngtcp2_pq_each(const ngtcp2_pq *pq, ngtcp2_pq_item_cb fun, void *arg) {
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (pq->length == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < pq->length; ++i) {
|
|
||||||
if ((*fun)(pq->q[i], arg)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
11
deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.h
vendored
11
deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.h
vendored
|
|
@ -109,17 +109,6 @@ int ngtcp2_pq_empty(const ngtcp2_pq *pq);
|
||||||
*/
|
*/
|
||||||
size_t ngtcp2_pq_size(const ngtcp2_pq *pq);
|
size_t ngtcp2_pq_size(const ngtcp2_pq *pq);
|
||||||
|
|
||||||
typedef int (*ngtcp2_pq_item_cb)(ngtcp2_pq_entry *item, void *arg);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ngtcp2_pq_each applies |fun| to each item in |pq|. The |arg| is
|
|
||||||
* passed as arg parameter to callback function. This function must
|
|
||||||
* not change the ordering key. If the return value from callback is
|
|
||||||
* nonzero, this function returns 1 immediately without iterating
|
|
||||||
* remaining items. Otherwise this function returns 0.
|
|
||||||
*/
|
|
||||||
int ngtcp2_pq_each(const ngtcp2_pq *pq, ngtcp2_pq_item_cb fun, void *arg);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_pq_remove removes |item| from |pq|. |pq| must contain
|
* ngtcp2_pq_remove removes |item| from |pq|. |pq| must contain
|
||||||
* |item| otherwise the behavior is undefined.
|
* |item| otherwise the behavior is undefined.
|
||||||
|
|
|
||||||
7
deps/ngtcp2/ngtcp2/lib/ngtcp2_pv.c
vendored
7
deps/ngtcp2/ngtcp2/lib/ngtcp2_pv.c
vendored
|
|
@ -170,3 +170,10 @@ void ngtcp2_pv_cancel_expired_timer(ngtcp2_pv *pv, ngtcp2_tstamp ts) {
|
||||||
|
|
||||||
pv->flags |= NGTCP2_PV_FLAG_CANCEL_TIMER;
|
pv->flags |= NGTCP2_PV_FLAG_CANCEL_TIMER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ngtcp2_pv_set_fallback(ngtcp2_pv *pv, const ngtcp2_dcid *dcid,
|
||||||
|
ngtcp2_duration pto) {
|
||||||
|
pv->flags |= NGTCP2_PV_FLAG_FALLBACK_PRESENT;
|
||||||
|
ngtcp2_dcid_copy(&pv->fallback_dcid, dcid);
|
||||||
|
pv->fallback_pto = pto;
|
||||||
|
}
|
||||||
|
|
|
||||||
18
deps/ngtcp2/ngtcp2/lib/ngtcp2_pv.h
vendored
18
deps/ngtcp2/ngtcp2/lib/ngtcp2_pv.h
vendored
|
|
@ -71,11 +71,13 @@ void ngtcp2_pv_entry_init(ngtcp2_pv_entry *pvent, const uint8_t *data,
|
||||||
/* NGTCP2_PV_FLAG_CANCEL_TIMER indicates that the expiry timer is
|
/* NGTCP2_PV_FLAG_CANCEL_TIMER indicates that the expiry timer is
|
||||||
cancelled. */
|
cancelled. */
|
||||||
#define NGTCP2_PV_FLAG_CANCEL_TIMER 0x02u
|
#define NGTCP2_PV_FLAG_CANCEL_TIMER 0x02u
|
||||||
/* NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE indicates that fallback DCID is
|
/* NGTCP2_PV_FLAG_FALLBACK_PRESENT indicates that a fallback
|
||||||
available in ngtcp2_pv. If path validation fails, fallback to the
|
Destination Connection ID and PTO are available in ngtcp2_pv. If
|
||||||
fallback DCID. If path validation succeeds, fallback DCID is
|
path validation fails, then fallback to them. If path validation
|
||||||
retired if it does not equal to the current DCID. */
|
succeeds, the fallback Destination Connection ID is retired if it
|
||||||
#define NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE 0x04u
|
is not zero length, and does not equal to the current Destination
|
||||||
|
Connection ID. */
|
||||||
|
#define NGTCP2_PV_FLAG_FALLBACK_PRESENT 0x04u
|
||||||
/* NGTCP2_PV_FLAG_PREFERRED_ADDR indicates that client is migrating to
|
/* NGTCP2_PV_FLAG_PREFERRED_ADDR indicates that client is migrating to
|
||||||
server's preferred address. This flag is only used by client. */
|
server's preferred address. This flag is only used by client. */
|
||||||
#define NGTCP2_PV_FLAG_PREFERRED_ADDR 0x10u
|
#define NGTCP2_PV_FLAG_PREFERRED_ADDR 0x10u
|
||||||
|
|
@ -191,4 +193,10 @@ ngtcp2_tstamp ngtcp2_pv_next_expiry(ngtcp2_pv *pv);
|
||||||
*/
|
*/
|
||||||
void ngtcp2_pv_cancel_expired_timer(ngtcp2_pv *pv, ngtcp2_tstamp ts);
|
void ngtcp2_pv_cancel_expired_timer(ngtcp2_pv *pv, ngtcp2_tstamp ts);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ngtcp2_pv_set_fallback sets |dcid| and |pto| as fallback.
|
||||||
|
*/
|
||||||
|
void ngtcp2_pv_set_fallback(ngtcp2_pv *pv, const ngtcp2_dcid *dcid,
|
||||||
|
ngtcp2_duration pto);
|
||||||
|
|
||||||
#endif /* !defined(NGTCP2_PV_H) */
|
#endif /* !defined(NGTCP2_PV_H) */
|
||||||
|
|
|
||||||
2
deps/ngtcp2/ngtcp2/lib/ngtcp2_range.c
vendored
2
deps/ngtcp2/ngtcp2/lib/ngtcp2_range.c
vendored
|
|
@ -32,7 +32,7 @@ void ngtcp2_range_init(ngtcp2_range *r, uint64_t begin, uint64_t end) {
|
||||||
|
|
||||||
ngtcp2_range ngtcp2_range_intersect(const ngtcp2_range *a,
|
ngtcp2_range ngtcp2_range_intersect(const ngtcp2_range *a,
|
||||||
const ngtcp2_range *b) {
|
const ngtcp2_range *b) {
|
||||||
ngtcp2_range r = {0, 0};
|
ngtcp2_range r = {0};
|
||||||
uint64_t begin = ngtcp2_max_uint64(a->begin, b->begin);
|
uint64_t begin = ngtcp2_max_uint64(a->begin, b->begin);
|
||||||
uint64_t end = ngtcp2_min_uint64(a->end, b->end);
|
uint64_t end = ngtcp2_min_uint64(a->end, b->end);
|
||||||
|
|
||||||
|
|
|
||||||
4
deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
vendored
4
deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
vendored
|
|
@ -122,4 +122,6 @@ void *ngtcp2_ringbuf_get(const ngtcp2_ringbuf *rb, size_t offset) {
|
||||||
return &rb->buf[offset * rb->size];
|
return &rb->buf[offset * rb->size];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_ringbuf_full(ngtcp2_ringbuf *rb) { return rb->len == rb->mask + 1; }
|
int ngtcp2_ringbuf_full(const ngtcp2_ringbuf *rb) {
|
||||||
|
return rb->len == rb->mask + 1;
|
||||||
|
}
|
||||||
|
|
|
||||||
2
deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h
vendored
2
deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.h
vendored
|
|
@ -113,7 +113,7 @@ void *ngtcp2_ringbuf_get(const ngtcp2_ringbuf *rb, size_t offset);
|
||||||
#define ngtcp2_ringbuf_len(RB) ((RB)->len)
|
#define ngtcp2_ringbuf_len(RB) ((RB)->len)
|
||||||
|
|
||||||
/* ngtcp2_ringbuf_full returns nonzero if |rb| is full. */
|
/* ngtcp2_ringbuf_full returns nonzero if |rb| is full. */
|
||||||
int ngtcp2_ringbuf_full(ngtcp2_ringbuf *rb);
|
int ngtcp2_ringbuf_full(const ngtcp2_ringbuf *rb);
|
||||||
|
|
||||||
/* ngtcp2_static_ringbuf_def defines ngtcp2_ringbuf struct wrapper
|
/* ngtcp2_static_ringbuf_def defines ngtcp2_ringbuf struct wrapper
|
||||||
which uses a statically allocated buffer. ngtcp2_ringbuf_free
|
which uses a statically allocated buffer. ngtcp2_ringbuf_free
|
||||||
|
|
|
||||||
11
deps/ngtcp2/ngtcp2/lib/ngtcp2_rob.c
vendored
11
deps/ngtcp2/ngtcp2/lib/ngtcp2_rob.c
vendored
|
|
@ -122,7 +122,10 @@ static int rob_write_data(ngtcp2_rob *rob, uint64_t offset, const uint8_t *data,
|
||||||
size_t n;
|
size_t n;
|
||||||
int rv;
|
int rv;
|
||||||
ngtcp2_rob_data *d;
|
ngtcp2_rob_data *d;
|
||||||
ngtcp2_range range = {offset, offset + len};
|
ngtcp2_range range = {
|
||||||
|
.begin = offset,
|
||||||
|
.end = offset + len,
|
||||||
|
};
|
||||||
ngtcp2_ksl_it it;
|
ngtcp2_ksl_it it;
|
||||||
|
|
||||||
for (it = ngtcp2_ksl_lower_bound_search(&rob->dataksl, &range,
|
for (it = ngtcp2_ksl_lower_bound_search(&rob->dataksl, &range,
|
||||||
|
|
@ -163,7 +166,11 @@ int ngtcp2_rob_push(ngtcp2_rob *rob, uint64_t offset, const uint8_t *data,
|
||||||
size_t datalen) {
|
size_t datalen) {
|
||||||
int rv;
|
int rv;
|
||||||
ngtcp2_rob_gap *g;
|
ngtcp2_rob_gap *g;
|
||||||
ngtcp2_range m, l, r, q = {offset, offset + datalen};
|
ngtcp2_range m, l, r;
|
||||||
|
ngtcp2_range q = {
|
||||||
|
.begin = offset,
|
||||||
|
.end = offset + datalen,
|
||||||
|
};
|
||||||
ngtcp2_ksl_it it;
|
ngtcp2_ksl_it it;
|
||||||
|
|
||||||
it = ngtcp2_ksl_lower_bound_search(&rob->gapksl, &q,
|
it = ngtcp2_ksl_lower_bound_search(&rob->gapksl, &q,
|
||||||
|
|
|
||||||
11
deps/ngtcp2/ngtcp2/lib/ngtcp2_rst.c
vendored
11
deps/ngtcp2/ngtcp2/lib/ngtcp2_rst.c
vendored
|
|
@ -46,6 +46,11 @@ void ngtcp2_rs_init(ngtcp2_rs *rs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ngtcp2_rst_init(ngtcp2_rst *rst) {
|
void ngtcp2_rst_init(ngtcp2_rst *rst) {
|
||||||
|
rst->last_seq = -1;
|
||||||
|
ngtcp2_rst_reset(rst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngtcp2_rst_reset(ngtcp2_rst *rst) {
|
||||||
ngtcp2_rs_init(&rst->rs);
|
ngtcp2_rs_init(&rst->rs);
|
||||||
rst->delivered = 0;
|
rst->delivered = 0;
|
||||||
rst->delivered_ts = 0;
|
rst->delivered_ts = 0;
|
||||||
|
|
@ -53,7 +58,7 @@ void ngtcp2_rst_init(ngtcp2_rst *rst) {
|
||||||
rst->app_limited = 0;
|
rst->app_limited = 0;
|
||||||
rst->is_cwnd_limited = 0;
|
rst->is_cwnd_limited = 0;
|
||||||
rst->lost = 0;
|
rst->lost = 0;
|
||||||
rst->last_seq = -1;
|
rst->valid_after_seq = rst->last_seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ngtcp2_rst_on_pkt_sent(ngtcp2_rst *rst, ngtcp2_rtb_entry *ent,
|
void ngtcp2_rst_on_pkt_sent(ngtcp2_rst *rst, ngtcp2_rtb_entry *ent,
|
||||||
|
|
@ -108,6 +113,10 @@ void ngtcp2_rst_update_rate_sample(ngtcp2_rst *rst, const ngtcp2_rtb_entry *ent,
|
||||||
ngtcp2_tstamp ts) {
|
ngtcp2_tstamp ts) {
|
||||||
ngtcp2_rs *rs = &rst->rs;
|
ngtcp2_rs *rs = &rst->rs;
|
||||||
|
|
||||||
|
if (ent->rst.end_seq <= rst->valid_after_seq) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rst->delivered += ent->pktlen;
|
rst->delivered += ent->pktlen;
|
||||||
rst->delivered_ts = ts;
|
rst->delivered_ts = ts;
|
||||||
|
|
||||||
|
|
|
||||||
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_rst.h
vendored
6
deps/ngtcp2/ngtcp2/lib/ngtcp2_rst.h
vendored
|
|
@ -73,11 +73,17 @@ typedef struct ngtcp2_rst {
|
||||||
across all packet number spaces, we can replace this with a
|
across all packet number spaces, we can replace this with a
|
||||||
packet number. */
|
packet number. */
|
||||||
int64_t last_seq;
|
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;
|
int is_cwnd_limited;
|
||||||
} ngtcp2_rst;
|
} ngtcp2_rst;
|
||||||
|
|
||||||
void ngtcp2_rst_init(ngtcp2_rst *rst);
|
void ngtcp2_rst_init(ngtcp2_rst *rst);
|
||||||
|
|
||||||
|
void ngtcp2_rst_reset(ngtcp2_rst *rst);
|
||||||
|
|
||||||
void ngtcp2_rst_on_pkt_sent(ngtcp2_rst *rst, ngtcp2_rtb_entry *ent,
|
void ngtcp2_rst_on_pkt_sent(ngtcp2_rst *rst, ngtcp2_rtb_entry *ent,
|
||||||
const ngtcp2_conn_stat *cstat);
|
const ngtcp2_conn_stat *cstat);
|
||||||
void ngtcp2_rst_on_ack_recv(ngtcp2_rst *rst, ngtcp2_conn_stat *cstat);
|
void ngtcp2_rst_on_ack_recv(ngtcp2_rst *rst, ngtcp2_conn_stat *cstat);
|
||||||
|
|
|
||||||
25
deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c
vendored
25
deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c
vendored
|
|
@ -101,7 +101,6 @@ void ngtcp2_rtb_init(ngtcp2_rtb *rtb, ngtcp2_rst *rst, ngtcp2_cc *cc,
|
||||||
rtb->probe_pkt_left = 0;
|
rtb->probe_pkt_left = 0;
|
||||||
rtb->cc_pkt_num = cc_pkt_num;
|
rtb->cc_pkt_num = cc_pkt_num;
|
||||||
rtb->cc_bytes_in_flight = 0;
|
rtb->cc_bytes_in_flight = 0;
|
||||||
rtb->persistent_congestion_start_ts = UINT64_MAX;
|
|
||||||
rtb->num_lost_pkts = 0;
|
rtb->num_lost_pkts = 0;
|
||||||
rtb->num_lost_pmtud_pkts = 0;
|
rtb->num_lost_pmtud_pkts = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -672,8 +671,8 @@ static int process_acked_pkt(ngtcp2_rtb_entry *ent, ngtcp2_conn *conn,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NGTCP2_FRAME_RETIRE_CONNECTION_ID:
|
case NGTCP2_FRAME_RETIRE_CONNECTION_ID:
|
||||||
ngtcp2_conn_untrack_retired_dcid_seq(conn,
|
ngtcp2_dcidtr_untrack_retired_seq(&conn->dcid.dtr,
|
||||||
frc->fr.retire_connection_id.seq);
|
frc->fr.retire_connection_id.seq);
|
||||||
break;
|
break;
|
||||||
case NGTCP2_FRAME_NEW_CONNECTION_ID:
|
case NGTCP2_FRAME_NEW_CONNECTION_ID:
|
||||||
assert(conn->scid.num_in_flight);
|
assert(conn->scid.num_in_flight);
|
||||||
|
|
@ -734,11 +733,11 @@ static void conn_verify_ecn(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
|
||||||
|
|
||||||
if ((ecn_acked && fr->type == NGTCP2_FRAME_ACK) ||
|
if ((ecn_acked && fr->type == NGTCP2_FRAME_ACK) ||
|
||||||
(fr->type == NGTCP2_FRAME_ACK_ECN &&
|
(fr->type == NGTCP2_FRAME_ACK_ECN &&
|
||||||
(pktns->rx.ecn.ack.ect0 > fr->ecn.ect0 ||
|
(pktns->acktr.ecn.ack.ect0 > fr->ecn.ect0 ||
|
||||||
pktns->rx.ecn.ack.ect1 > fr->ecn.ect1 ||
|
pktns->acktr.ecn.ack.ect1 > fr->ecn.ect1 ||
|
||||||
pktns->rx.ecn.ack.ce > fr->ecn.ce ||
|
pktns->acktr.ecn.ack.ce > fr->ecn.ce ||
|
||||||
(fr->ecn.ect0 - pktns->rx.ecn.ack.ect0) +
|
(fr->ecn.ect0 - pktns->acktr.ecn.ack.ect0) +
|
||||||
(fr->ecn.ce - pktns->rx.ecn.ack.ce) <
|
(fr->ecn.ce - pktns->acktr.ecn.ack.ce) <
|
||||||
ecn_acked ||
|
ecn_acked ||
|
||||||
fr->ecn.ect0 > pktns->tx.ecn.ect0 || fr->ecn.ect1))) {
|
fr->ecn.ect0 > pktns->tx.ecn.ect0 || fr->ecn.ect1))) {
|
||||||
ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
|
ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
|
||||||
|
|
@ -755,13 +754,13 @@ static void conn_verify_ecn(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
|
||||||
|
|
||||||
if (fr->type == NGTCP2_FRAME_ACK_ECN) {
|
if (fr->type == NGTCP2_FRAME_ACK_ECN) {
|
||||||
if (cc->congestion_event && largest_pkt_sent_ts != UINT64_MAX &&
|
if (cc->congestion_event && largest_pkt_sent_ts != UINT64_MAX &&
|
||||||
fr->ecn.ce > pktns->rx.ecn.ack.ce) {
|
fr->ecn.ce > pktns->acktr.ecn.ack.ce) {
|
||||||
cc->congestion_event(cc, cstat, largest_pkt_sent_ts, 0, ts);
|
cc->congestion_event(cc, cstat, largest_pkt_sent_ts, 0, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
pktns->rx.ecn.ack.ect0 = fr->ecn.ect0;
|
pktns->acktr.ecn.ack.ect0 = fr->ecn.ect0;
|
||||||
pktns->rx.ecn.ack.ect1 = fr->ecn.ect1;
|
pktns->acktr.ecn.ack.ect1 = fr->ecn.ect1;
|
||||||
pktns->rx.ecn.ack.ce = fr->ecn.ce;
|
pktns->acktr.ecn.ack.ce = fr->ecn.ce;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1052,7 +1051,7 @@ static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost,
|
||||||
max_ack_delay) *
|
max_ack_delay) *
|
||||||
NGTCP2_PERSISTENT_CONGESTION_THRESHOLD;
|
NGTCP2_PERSISTENT_CONGESTION_THRESHOLD;
|
||||||
|
|
||||||
start_ts = ngtcp2_max_uint64(rtb->persistent_congestion_start_ts,
|
start_ts = ngtcp2_max_uint64(conn->handshake_confirmed_ts,
|
||||||
cstat->first_rtt_sample_ts);
|
cstat->first_rtt_sample_ts);
|
||||||
|
|
||||||
for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
|
for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
|
||||||
|
|
|
||||||
4
deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.h
vendored
4
deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.h
vendored
|
|
@ -184,10 +184,6 @@ typedef struct ngtcp2_rtb {
|
||||||
count a packet whose packet number is greater than or equals to
|
count a packet whose packet number is greater than or equals to
|
||||||
cc_pkt_num. */
|
cc_pkt_num. */
|
||||||
uint64_t cc_bytes_in_flight;
|
uint64_t cc_bytes_in_flight;
|
||||||
/* persistent_congestion_start_ts is the time when persistent
|
|
||||||
congestion evaluation is started. It happens roughly after
|
|
||||||
handshake is confirmed. */
|
|
||||||
ngtcp2_tstamp persistent_congestion_start_ts;
|
|
||||||
/* num_lost_pkts is the number entries in ents which has
|
/* num_lost_pkts is the number entries in ents which has
|
||||||
NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED flag set. */
|
NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED flag set. */
|
||||||
size_t num_lost_pkts;
|
size_t num_lost_pkts;
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@ static int decode_varint(uint64_t *pdest, const uint8_t **pp,
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ngtcp2_get_uvarintlen(p);
|
len = ngtcp2_get_uvarintlen(p);
|
||||||
if ((uint64_t)(end - p) < len) {
|
if ((size_t)(end - p) < len) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -530,8 +530,11 @@ int ngtcp2_transport_params_decode_versioned(int transport_params_version,
|
||||||
params->active_connection_id_limit =
|
params->active_connection_id_limit =
|
||||||
NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
|
NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
|
||||||
|
|
||||||
p = data;
|
p = end = data;
|
||||||
end = data + datalen;
|
|
||||||
|
if (datalen) {
|
||||||
|
end += datalen;
|
||||||
|
}
|
||||||
|
|
||||||
for (; (size_t)(end - p) >= 2;) {
|
for (; (size_t)(end - p) >= 2;) {
|
||||||
if (decode_varint(¶m_type, &p, end) != 0) {
|
if (decode_varint(¶m_type, &p, end) != 0) {
|
||||||
|
|
|
||||||
34
deps/ngtcp2/ngtcp2/lib/ngtcp2_vec.c
vendored
34
deps/ngtcp2/ngtcp2/lib/ngtcp2_vec.c
vendored
|
|
@ -35,33 +35,6 @@ ngtcp2_vec *ngtcp2_vec_init(ngtcp2_vec *vec, const uint8_t *base, size_t len) {
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngtcp2_vec_new(ngtcp2_vec **pvec, const uint8_t *data, size_t datalen,
|
|
||||||
const ngtcp2_mem *mem) {
|
|
||||||
size_t len;
|
|
||||||
uint8_t *p;
|
|
||||||
|
|
||||||
len = sizeof(ngtcp2_vec) + datalen;
|
|
||||||
|
|
||||||
*pvec = ngtcp2_mem_malloc(mem, len);
|
|
||||||
if (*pvec == NULL) {
|
|
||||||
return NGTCP2_ERR_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = (uint8_t *)(*pvec) + sizeof(ngtcp2_vec);
|
|
||||||
(*pvec)->base = p;
|
|
||||||
(*pvec)->len = datalen;
|
|
||||||
|
|
||||||
if (datalen) {
|
|
||||||
/* p = */ ngtcp2_cpymem(p, data, datalen);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ngtcp2_vec_del(ngtcp2_vec *vec, const ngtcp2_mem *mem) {
|
|
||||||
ngtcp2_mem_free(mem, vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t ngtcp2_vec_len(const ngtcp2_vec *vec, size_t n) {
|
uint64_t ngtcp2_vec_len(const ngtcp2_vec *vec, size_t n) {
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t res = 0;
|
size_t res = 0;
|
||||||
|
|
@ -225,13 +198,14 @@ size_t ngtcp2_vec_copy_at_most(ngtcp2_vec *dst, size_t dstcnt,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst[j] = src[i];
|
if (src[i].len > left) {
|
||||||
|
dst[j].base = src[i].base;
|
||||||
if (dst[j].len > left) {
|
|
||||||
dst[j].len = left;
|
dst[j].len = left;
|
||||||
|
|
||||||
return j + 1;
|
return j + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dst[j] = src[i];
|
||||||
left -= dst[j].len;
|
left -= dst[j].len;
|
||||||
++i;
|
++i;
|
||||||
++j;
|
++j;
|
||||||
|
|
|
||||||
16
deps/ngtcp2/ngtcp2/lib/ngtcp2_vec.h
vendored
16
deps/ngtcp2/ngtcp2/lib/ngtcp2_vec.h
vendored
|
|
@ -46,22 +46,6 @@
|
||||||
*/
|
*/
|
||||||
ngtcp2_vec *ngtcp2_vec_init(ngtcp2_vec *vec, const uint8_t *base, size_t len);
|
ngtcp2_vec *ngtcp2_vec_init(ngtcp2_vec *vec, const uint8_t *base, size_t len);
|
||||||
|
|
||||||
/*
|
|
||||||
* ngtcp2_vec_new allocates and initializes |*pvec| with given |data|
|
|
||||||
* of length |datalen|. This function allocates memory for |*pvec|
|
|
||||||
* and the given data with a single allocation, and the contents
|
|
||||||
* pointed by |data| is copied into the allocated memory space. To
|
|
||||||
* free the allocated memory, call ngtcp2_vec_del.
|
|
||||||
*/
|
|
||||||
int ngtcp2_vec_new(ngtcp2_vec **pvec, const uint8_t *data, size_t datalen,
|
|
||||||
const ngtcp2_mem *mem);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ngtcp2_vec_del frees the memory allocated by |vec| which is
|
|
||||||
* allocated and initialized by ngtcp2_vec_new.
|
|
||||||
*/
|
|
||||||
void ngtcp2_vec_del(ngtcp2_vec *vec, const ngtcp2_mem *mem);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ngtcp2_vec_len returns the sum of length in |vec| of |n| elements.
|
* ngtcp2_vec_len returns the sum of length in |vec| of |n| elements.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user