summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Doskočil <jan.doskocil@nic.cz>2024-11-20 16:54:59 +0100
committerJan Doskočil <jan.doskocil@nic.cz>2024-11-20 19:15:52 +0100
commitde3c09db2071b6b519a2ab7f8b7b5a0e3b9a8b94 (patch)
tree5f5f383eae0838fe00679f8067dc461d8ee54abf
parentscripts: update_ngtcp2.sh for semi-automatic embedded libngtcp2 updates (diff)
downloadknot-de3c09db2071b6b519a2ab7f8b7b5a0e3b9a8b94.tar.xz
knot-de3c09db2071b6b519a2ab7f8b7b5a0e3b9a8b94.zip
libngtcp2: update to 1.9.0
-rw-r--r--src/contrib/libngtcp2/ngtcp2/crypto/shared.c200
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c9
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h4
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_balloc.h2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c51
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h10
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_gaptr.c16
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c73
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h104
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h36
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.h2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c16
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c16
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c12
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.h2
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c7
-rw-r--r--src/contrib/libngtcp2/ngtcp2/ngtcp2.h7
-rw-r--r--src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h118
-rw-r--r--src/contrib/libngtcp2/ngtcp2/version.h4
22 files changed, 573 insertions, 122 deletions
diff --git a/src/contrib/libngtcp2/ngtcp2/crypto/shared.c b/src/contrib/libngtcp2/ngtcp2/crypto/shared.c
index 6088b80c3..98cd4de7e 100644
--- a/src/contrib/libngtcp2/ngtcp2/crypto/shared.c
+++ b/src/contrib/libngtcp2/ngtcp2/crypto/shared.c
@@ -1080,6 +1080,206 @@ int ngtcp2_crypto_verify_retry_token(
return 0;
}
+static size_t crypto_generate_retry_token_aad2(uint8_t *dest, uint32_t version,
+ const ngtcp2_cid *retry_scid) {
+ uint8_t *p = dest;
+
+ version = ngtcp2_htonl(version);
+ memcpy(p, &version, sizeof(version));
+ p += sizeof(version);
+ memcpy(p, retry_scid->data, retry_scid->datalen);
+ p += retry_scid->datalen;
+
+ return (size_t)(p - dest);
+}
+
+static const uint8_t retry_token_info_prefix2[] = "retry_token2";
+
+ngtcp2_ssize ngtcp2_crypto_generate_retry_token2(
+ uint8_t *token, const uint8_t *secret, size_t secretlen, uint32_t version,
+ const ngtcp2_sockaddr *remote_addr, ngtcp2_socklen remote_addrlen,
+ const ngtcp2_cid *retry_scid, const ngtcp2_cid *odcid, ngtcp2_tstamp ts) {
+ uint8_t plaintext[sizeof(ngtcp2_sockaddr_union) + /* cid len = */ 1 +
+ NGTCP2_MAX_CIDLEN + sizeof(ngtcp2_tstamp)];
+ uint8_t rand_data[NGTCP2_CRYPTO_TOKEN_RAND_DATALEN];
+ uint8_t key[16];
+ uint8_t iv[12];
+ size_t keylen;
+ size_t ivlen;
+ ngtcp2_crypto_aead aead;
+ ngtcp2_crypto_md md;
+ ngtcp2_crypto_aead_ctx aead_ctx;
+ uint8_t aad[sizeof(version) + NGTCP2_MAX_CIDLEN];
+ size_t aadlen;
+ uint8_t *p = plaintext;
+ ngtcp2_tstamp ts_be = ngtcp2_htonl64(ts);
+ int rv;
+
+ assert((size_t)remote_addrlen <= sizeof(ngtcp2_sockaddr_union));
+
+ memset(plaintext, 0, sizeof(plaintext));
+
+ memcpy(p, remote_addr, (size_t)remote_addrlen);
+ p += sizeof(ngtcp2_sockaddr_union);
+ *p++ = (uint8_t)odcid->datalen;
+ memcpy(p, odcid->data, odcid->datalen);
+ p += NGTCP2_MAX_CIDLEN;
+ memcpy(p, &ts_be, sizeof(ts_be));
+
+ assert((size_t)(p + sizeof(ts_be) - plaintext) == sizeof(plaintext));
+
+ if (ngtcp2_crypto_random(rand_data, sizeof(rand_data)) != 0) {
+ return -1;
+ }
+
+ ngtcp2_crypto_aead_aes_128_gcm(&aead);
+ ngtcp2_crypto_md_sha256(&md);
+
+ keylen = ngtcp2_crypto_aead_keylen(&aead);
+ ivlen = ngtcp2_crypto_aead_noncelen(&aead);
+
+ assert(sizeof(key) == keylen);
+ assert(sizeof(iv) == ivlen);
+
+ if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
+ rand_data, sizeof(rand_data),
+ retry_token_info_prefix2,
+ sizeof(retry_token_info_prefix2) - 1) != 0) {
+ return -1;
+ }
+
+ aadlen = crypto_generate_retry_token_aad2(aad, version, retry_scid);
+
+ p = token;
+ *p++ = NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY2;
+
+ if (ngtcp2_crypto_aead_ctx_encrypt_init(&aead_ctx, &aead, key, ivlen) != 0) {
+ return -1;
+ }
+
+ rv = ngtcp2_crypto_encrypt(p, &aead, &aead_ctx, plaintext, sizeof(plaintext),
+ iv, ivlen, aad, aadlen);
+
+ ngtcp2_crypto_aead_ctx_free(&aead_ctx);
+
+ if (rv != 0) {
+ return -1;
+ }
+
+ p += sizeof(plaintext) + aead.max_overhead;
+ memcpy(p, rand_data, sizeof(rand_data));
+ p += sizeof(rand_data);
+
+ return p - token;
+}
+
+int ngtcp2_crypto_verify_retry_token2(
+ ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen,
+ const uint8_t *secret, size_t secretlen, uint32_t version,
+ const ngtcp2_sockaddr *remote_addr, ngtcp2_socklen remote_addrlen,
+ const ngtcp2_cid *dcid, ngtcp2_duration timeout, ngtcp2_tstamp ts) {
+ uint8_t plaintext[sizeof(ngtcp2_sockaddr_union) + /* cid len = */ 1 +
+ NGTCP2_MAX_CIDLEN + sizeof(ngtcp2_tstamp)];
+ uint8_t key[16];
+ uint8_t iv[12];
+ size_t keylen;
+ size_t ivlen;
+ ngtcp2_crypto_aead_ctx aead_ctx;
+ ngtcp2_crypto_aead aead;
+ ngtcp2_crypto_md md;
+ uint8_t aad[sizeof(version) + NGTCP2_MAX_CIDLEN];
+ size_t aadlen;
+ const uint8_t *rand_data;
+ const uint8_t *ciphertext;
+ size_t ciphertextlen;
+ size_t cil;
+ int rv;
+ ngtcp2_tstamp gen_ts;
+ ngtcp2_sockaddr_union addr;
+ size_t addrlen;
+ uint8_t *p;
+
+ assert((size_t)remote_addrlen <= sizeof(ngtcp2_sockaddr_union));
+
+ if (tokenlen != NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN2 ||
+ token[0] != NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY2) {
+ return NGTCP2_CRYPTO_ERR_UNREADABLE_TOKEN;
+ }
+
+ rand_data = token + tokenlen - NGTCP2_CRYPTO_TOKEN_RAND_DATALEN;
+ ciphertext = token + 1;
+ ciphertextlen = (size_t)(rand_data - ciphertext);
+
+ ngtcp2_crypto_aead_aes_128_gcm(&aead);
+ ngtcp2_crypto_md_sha256(&md);
+
+ keylen = ngtcp2_crypto_aead_keylen(&aead);
+ ivlen = ngtcp2_crypto_aead_noncelen(&aead);
+
+ assert(sizeof(key) == keylen);
+ assert(sizeof(iv) == ivlen);
+
+ if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
+ rand_data, NGTCP2_CRYPTO_TOKEN_RAND_DATALEN,
+ retry_token_info_prefix2,
+ sizeof(retry_token_info_prefix2) - 1) != 0) {
+ return NGTCP2_CRYPTO_ERR_INTERNAL;
+ }
+
+ aadlen = crypto_generate_retry_token_aad2(aad, version, dcid);
+
+ if (ngtcp2_crypto_aead_ctx_decrypt_init(&aead_ctx, &aead, key, ivlen) != 0) {
+ return NGTCP2_CRYPTO_ERR_INTERNAL;
+ }
+
+ rv = ngtcp2_crypto_decrypt(plaintext, &aead, &aead_ctx, ciphertext,
+ ciphertextlen, iv, ivlen, aad, aadlen);
+
+ ngtcp2_crypto_aead_ctx_free(&aead_ctx);
+
+ if (rv != 0) {
+ return NGTCP2_CRYPTO_ERR_UNREADABLE_TOKEN;
+ }
+
+ p = plaintext;
+
+ memcpy(&addr, p, sizeof(addr));
+
+ switch (addr.sa.sa_family) {
+ case NGTCP2_AF_INET:
+ addrlen = sizeof(ngtcp2_sockaddr_in);
+ break;
+ case NGTCP2_AF_INET6:
+ addrlen = sizeof(ngtcp2_sockaddr_in6);
+ break;
+ default:
+ return NGTCP2_CRYPTO_ERR_VERIFY_TOKEN;
+ }
+
+ if (addrlen != (size_t)remote_addrlen ||
+ memcmp(&addr, remote_addr, addrlen) != 0) {
+ return NGTCP2_CRYPTO_ERR_VERIFY_TOKEN;
+ }
+
+ p += sizeof(addr);
+ cil = *p++;
+
+ if (cil != 0 && (cil < NGTCP2_MIN_CIDLEN || cil > NGTCP2_MAX_CIDLEN)) {
+ return NGTCP2_CRYPTO_ERR_VERIFY_TOKEN;
+ }
+
+ memcpy(&gen_ts, p + NGTCP2_MAX_CIDLEN, sizeof(gen_ts));
+
+ gen_ts = ngtcp2_ntohl64(gen_ts);
+ if (gen_ts + timeout <= ts) {
+ return NGTCP2_CRYPTO_ERR_VERIFY_TOKEN;
+ }
+
+ ngtcp2_cid_init(odcid, p, cil);
+
+ return 0;
+}
+
static size_t crypto_generate_regular_token_aad(uint8_t *dest,
const ngtcp2_sockaddr *sa) {
const uint8_t *addr;
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c
index d5508ba89..0e5bfe069 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.c
@@ -29,7 +29,7 @@
#include "ngtcp2_macro.h"
#include "ngtcp2_tstamp.h"
-ngtcp2_objalloc_def(acktr_entry, ngtcp2_acktr_entry, oplent);
+ngtcp2_objalloc_def(acktr_entry, ngtcp2_acktr_entry, oplent)
static void acktr_entry_init(ngtcp2_acktr_entry *ent, int64_t pkt_num,
ngtcp2_tstamp tstamp) {
@@ -56,10 +56,6 @@ void ngtcp2_acktr_entry_objalloc_del(ngtcp2_acktr_entry *ent,
ngtcp2_objalloc_acktr_entry_release(objalloc, ent);
}
-static int greater(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) {
- return *(int64_t *)lhs > *(int64_t *)rhs;
-}
-
void ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log,
const ngtcp2_mem *mem) {
ngtcp2_objalloc_acktr_entry_init(&acktr->objalloc, NGTCP2_ACKTR_MAX_ENT + 1,
@@ -67,7 +63,8 @@ void ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log,
ngtcp2_static_ringbuf_acks_init(&acktr->acks);
- ngtcp2_ksl_init(&acktr->ents, greater, sizeof(int64_t), mem);
+ ngtcp2_ksl_init(&acktr->ents, ngtcp2_ksl_int64_greater,
+ ngtcp2_ksl_int64_greater_search, sizeof(int64_t), mem);
acktr->log = log;
acktr->flags = NGTCP2_ACKTR_FLAG_NONE;
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h
index 4ef420723..16aee42f2 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_acktr.h
@@ -65,7 +65,7 @@ typedef struct ngtcp2_acktr_entry {
};
} ngtcp2_acktr_entry;
-ngtcp2_objalloc_decl(acktr_entry, ngtcp2_acktr_entry, oplent);
+ngtcp2_objalloc_decl(acktr_entry, ngtcp2_acktr_entry, oplent)
/*
* ngtcp2_acktr_entry_objalloc_new allocates memory for ent, and
@@ -108,7 +108,7 @@ typedef struct ngtcp2_acktr_ack_entry {
expired and canceled. */
#define NGTCP2_ACKTR_FLAG_CANCEL_TIMER 0x0100u
-ngtcp2_static_ringbuf_def(acks, 32, sizeof(ngtcp2_acktr_ack_entry));
+ngtcp2_static_ringbuf_def(acks, 32, sizeof(ngtcp2_acktr_ack_entry))
/*
* ngtcp2_acktr tracks received packets which we have to send ack.
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_balloc.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_balloc.h
index e69e7efc6..c0e2a3f75 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_balloc.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_balloc.h
@@ -63,7 +63,7 @@ typedef struct ngtcp2_balloc {
/*
* ngtcp2_balloc_init initializes |balloc| with |blklen| which is the
- * size of memory block.
+ * size of memory block. |blklen| must be divisible by 16.
*/
void ngtcp2_balloc_init(ngtcp2_balloc *balloc, size_t blklen,
const ngtcp2_mem *mem);
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
index 5a66c1870..8777ca4c8 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
@@ -1149,7 +1149,7 @@ static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t gain_h) {
return bbr->initial_cwnd;
}
- bdp = bbr->bw * bbr->min_rtt / NGTCP2_SECONDS;
+ bdp = ngtcp2_max_uint64(bbr->bw * bbr->min_rtt / NGTCP2_SECONDS, 1);
return (uint64_t)(bdp * gain_h / 100);
}
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
index dff8d5945..0f67ac09b 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
@@ -51,8 +51,12 @@
/* NGTCP2_MIN_COALESCED_PAYLOADLEN is the minimum length of QUIC
packet payload that should be coalesced to a long packet. */
#define NGTCP2_MIN_COALESCED_PAYLOADLEN 128
+/* NGTCP2_MAX_ACK_PER_PKT is the maximum number of ACK frame per an
+ incoming QUIC packet to process. ACK frames that exceed this limit
+ are not processed. */
+#define NGTCP2_MAX_ACK_PER_PKT 1
-ngtcp2_objalloc_def(strm, ngtcp2_strm, oplent);
+ngtcp2_objalloc_def(strm, ngtcp2_strm, oplent)
/*
* conn_local_stream returns nonzero if |stream_id| indicates that it
@@ -767,6 +771,8 @@ static int cid_less(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) {
return ngtcp2_cid_less(lhs, rhs);
}
+ngtcp2_ksl_search_def(cid_less, cid_less)
+
static int retired_ts_less(const ngtcp2_pq_entry *lhs,
const ngtcp2_pq_entry *rhs) {
const ngtcp2_scid *a = ngtcp2_struct_of(lhs, ngtcp2_scid, pe);
@@ -1159,7 +1165,8 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
ngtcp2_gaptr_init(&(*pconn)->dcid.seqgap, mem);
- ngtcp2_ksl_init(&(*pconn)->scid.set, cid_less, sizeof(ngtcp2_cid), mem);
+ ngtcp2_ksl_init(&(*pconn)->scid.set, cid_less, ksl_cid_less_search,
+ sizeof(ngtcp2_cid), mem);
ngtcp2_pq_init(&(*pconn)->scid.used, retired_ts_less, mem);
@@ -1657,8 +1664,9 @@ static int conn_ensure_ack_ranges(ngtcp2_conn *conn, size_t n) {
* ACK.
*/
static ngtcp2_duration conn_compute_ack_delay(ngtcp2_conn *conn) {
- return ngtcp2_min_uint64(conn->local.transport_params.max_ack_delay,
- conn->cstat.smoothed_rtt / 8);
+ return ngtcp2_min_uint64(
+ conn->local.transport_params.max_ack_delay,
+ ngtcp2_max_uint64(conn->cstat.smoothed_rtt / 8, NGTCP2_NANOSECONDS));
}
int ngtcp2_conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
@@ -2901,7 +2909,7 @@ static int conn_should_send_max_stream_data(ngtcp2_conn *conn,
uint64_t inc = strm->rx.unsent_max_offset - strm->rx.max_offset;
(void)conn;
- return strm->rx.window < 2 * inc;
+ return strm->rx.window < 4 * inc;
}
/*
@@ -2911,7 +2919,7 @@ static int conn_should_send_max_stream_data(ngtcp2_conn *conn,
static int conn_should_send_max_data(ngtcp2_conn *conn) {
uint64_t inc = conn->rx.unsent_max_offset - conn->rx.max_offset;
- return conn->rx.window < 2 * inc;
+ return conn->rx.window < 4 * inc;
}
/*
@@ -3423,10 +3431,9 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
ngtcp2_acktr_commit_ack(&pktns->acktr);
ngtcp2_acktr_add_ack(&pktns->acktr, hd->pkt_num,
ackfr->ack.largest_ack);
- if (type == NGTCP2_PKT_1RTT) {
- conn_handle_unconfirmed_key_update_from_remote(
- conn, ackfr->ack.largest_ack, ts);
- }
+ assert(NGTCP2_PKT_1RTT == type);
+ conn_handle_unconfirmed_key_update_from_remote(
+ conn, ackfr->ack.largest_ack, ts);
pkt_empty = 0;
}
}
@@ -4209,7 +4216,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
ngtcp2_rtb_entry_objalloc_new(&ent, hd, NULL, ts, (size_t)nwrite,
rtb_entry_flags, &conn->rtb_entry_objalloc);
if (rv != 0) {
- assert(ngtcp2_err_is_fatal((int)nwrite));
+ assert(ngtcp2_err_is_fatal(rv));
return rv;
}
@@ -6109,6 +6116,7 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
ngtcp2_strm *crypto;
ngtcp2_encryption_level encryption_level;
int invalid_reserved_bits = 0;
+ size_t num_ack_processed = 0;
if (pktlen == 0) {
return 0;
@@ -6561,6 +6569,9 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
switch (fr->type) {
case NGTCP2_FRAME_ACK:
case NGTCP2_FRAME_ACK_ECN:
+ if (num_ack_processed >= NGTCP2_MAX_ACK_PER_PKT) {
+ break;
+ }
if (!conn->server && hd.type == NGTCP2_PKT_HANDSHAKE) {
conn->flags |= NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED;
}
@@ -6568,6 +6579,7 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
if (rv != 0) {
return rv;
}
+ ++num_ack_processed;
break;
case NGTCP2_FRAME_PADDING:
break;
@@ -8676,6 +8688,7 @@ conn_recv_delayed_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_pkt_info *pi,
int rv;
int require_ack = 0;
ngtcp2_pktns *pktns;
+ size_t num_ack_processed = 0;
assert(hd->type == NGTCP2_PKT_HANDSHAKE);
@@ -8710,6 +8723,9 @@ conn_recv_delayed_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_pkt_info *pi,
switch (fr->type) {
case NGTCP2_FRAME_ACK:
case NGTCP2_FRAME_ACK_ECN:
+ if (num_ack_processed >= NGTCP2_MAX_ACK_PER_PKT) {
+ break;
+ }
if (!conn->server) {
conn->flags |= NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED;
}
@@ -8717,6 +8733,7 @@ conn_recv_delayed_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_pkt_info *pi,
if (rv != 0) {
return rv;
}
+ ++num_ack_processed;
break;
case NGTCP2_FRAME_PADDING:
break;
@@ -8878,6 +8895,7 @@ static ngtcp2_ssize conn_recv_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
int recv_ncid = 0;
int new_cid_used = 0;
int path_challenge_recved = 0;
+ size_t num_ack_processed = 0;
if (conn->server && conn->local.transport_params.disable_active_migration &&
!ngtcp2_path_eq(&conn->dcid.current.ps.path, path) &&
@@ -9228,6 +9246,9 @@ static ngtcp2_ssize conn_recv_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
switch (fr->type) {
case NGTCP2_FRAME_ACK:
case NGTCP2_FRAME_ACK_ECN:
+ if (num_ack_processed >= NGTCP2_MAX_ACK_PER_PKT) {
+ break;
+ }
if (!conn->server) {
conn->flags |= NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED;
}
@@ -9236,6 +9257,7 @@ static ngtcp2_ssize conn_recv_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
return rv;
}
non_probing_pkt = 1;
+ ++num_ack_processed;
break;
case NGTCP2_FRAME_STREAM:
rv = conn_recv_stream(conn, &fr->stream);
@@ -11703,7 +11725,10 @@ static ngtcp2_ssize conn_write_vmsg_wrapper(ngtcp2_conn *conn,
if (cstat->bytes_in_flight >= cstat->cwnd) {
conn->rst.is_cwnd_limited = 1;
- } else if (nwrite == 0 && conn_pacing_pkt_tx_allowed(conn, ts)) {
+ } else if ((cstat->cwnd >= cstat->ssthresh ||
+ cstat->bytes_in_flight * 2 < cstat->cwnd) &&
+ nwrite == 0 && conn_pacing_pkt_tx_allowed(conn, ts) &&
+ (conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED)) {
conn->rst.app_limited = conn->rst.delivered + cstat->bytes_in_flight;
if (conn->rst.app_limited == 0) {
@@ -12793,6 +12818,8 @@ int ngtcp2_conn_update_rtt(ngtcp2_conn *conn, ngtcp2_duration rtt,
ngtcp2_duration ack_delay, ngtcp2_tstamp ts) {
ngtcp2_conn_stat *cstat = &conn->cstat;
+ assert(rtt > 0);
+
if (cstat->min_rtt == UINT64_MAX) {
cstat->latest_rtt = rtt;
cstat->min_rtt = rtt;
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h
index 562628d08..55073fcc8 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.h
@@ -337,15 +337,15 @@ typedef struct ngtcp2_early_transport_params {
} ngtcp2_early_transport_params;
ngtcp2_static_ringbuf_def(dcid_bound, NGTCP2_MAX_BOUND_DCID_POOL_SIZE,
- sizeof(ngtcp2_dcid));
+ sizeof(ngtcp2_dcid))
ngtcp2_static_ringbuf_def(dcid_unused, NGTCP2_MAX_DCID_POOL_SIZE,
- sizeof(ngtcp2_dcid));
+ sizeof(ngtcp2_dcid))
ngtcp2_static_ringbuf_def(dcid_retired, NGTCP2_MAX_DCID_RETIRED_SIZE,
- sizeof(ngtcp2_dcid));
+ sizeof(ngtcp2_dcid))
ngtcp2_static_ringbuf_def(path_challenge, 4,
- sizeof(ngtcp2_path_challenge_entry));
+ sizeof(ngtcp2_path_challenge_entry))
-ngtcp2_objalloc_decl(strm, ngtcp2_strm, oplent);
+ngtcp2_objalloc_decl(strm, ngtcp2_strm, oplent)
struct ngtcp2_conn {
ngtcp2_objalloc frc_objalloc;
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c
index cf0f11717..6a8a22c3f 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.c
@@ -27,7 +27,7 @@
#include <string.h>
#include <assert.h>
-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));
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h
index c38f1aeac..e5b6779c0 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_frame_chain.h
@@ -74,7 +74,7 @@ struct ngtcp2_frame_chain {
};
};
-ngtcp2_objalloc_decl(frame_chain, ngtcp2_frame_chain, oplent);
+ngtcp2_objalloc_decl(frame_chain, ngtcp2_frame_chain, oplent)
/*
* ngtcp2_bind_frame_chains binds two frame chains |a| and |b| using
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_gaptr.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_gaptr.c
index 1475c2286..3bfa39848 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_gaptr.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_gaptr.c
@@ -28,8 +28,8 @@
#include <assert.h>
void ngtcp2_gaptr_init(ngtcp2_gaptr *gaptr, const ngtcp2_mem *mem) {
- ngtcp2_ksl_init(&gaptr->gap, ngtcp2_ksl_range_compar, sizeof(ngtcp2_range),
- mem);
+ ngtcp2_ksl_init(&gaptr->gap, ngtcp2_ksl_range_compar, ngtcp2_ksl_range_search,
+ sizeof(ngtcp2_range), mem);
gaptr->mem = mem;
}
@@ -60,8 +60,8 @@ int ngtcp2_gaptr_push(ngtcp2_gaptr *gaptr, uint64_t offset, uint64_t datalen) {
}
}
- it = ngtcp2_ksl_lower_bound_compar(&gaptr->gap, &q,
- ngtcp2_ksl_range_exclusive_compar);
+ it = ngtcp2_ksl_lower_bound_search(&gaptr->gap, &q,
+ ngtcp2_ksl_range_exclusive_search);
for (; !ngtcp2_ksl_it_end(&it);) {
k = *(ngtcp2_range *)ngtcp2_ksl_it_key(&it);
@@ -118,8 +118,8 @@ ngtcp2_range ngtcp2_gaptr_get_first_gap_after(const ngtcp2_gaptr *gaptr,
return r;
}
- it = ngtcp2_ksl_lower_bound_compar(&gaptr->gap, &q,
- ngtcp2_ksl_range_exclusive_compar);
+ it = ngtcp2_ksl_lower_bound_search(&gaptr->gap, &q,
+ ngtcp2_ksl_range_exclusive_search);
assert(!ngtcp2_ksl_it_end(&it));
@@ -136,8 +136,8 @@ int ngtcp2_gaptr_is_pushed(const ngtcp2_gaptr *gaptr, uint64_t offset,
return 0;
}
- it = ngtcp2_ksl_lower_bound_compar(&gaptr->gap, &q,
- ngtcp2_ksl_range_exclusive_compar);
+ it = ngtcp2_ksl_lower_bound_search(&gaptr->gap, &q,
+ ngtcp2_ksl_range_exclusive_search);
m = ngtcp2_range_intersect(&q, (ngtcp2_range *)ngtcp2_ksl_it_key(&it));
return ngtcp2_range_len(&m) == 0;
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c
index 2280b462c..5e74f6472 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.c
@@ -35,7 +35,7 @@
static ngtcp2_ksl_blk null_blk = {{{NULL, NULL, 0, 0, {0}}}};
-ngtcp2_objalloc_def(ksl_blk, ngtcp2_ksl_blk, oplent);
+ngtcp2_objalloc_def(ksl_blk, ngtcp2_ksl_blk, oplent)
static size_t ksl_nodelen(size_t keylen) {
assert(keylen >= sizeof(uint64_t));
@@ -57,7 +57,8 @@ static void ksl_node_set_key(ngtcp2_ksl *ksl, ngtcp2_ksl_node *node,
memcpy(node->key, key, ksl->keylen);
}
-void ngtcp2_ksl_init(ngtcp2_ksl *ksl, ngtcp2_ksl_compar compar, size_t keylen,
+void ngtcp2_ksl_init(ngtcp2_ksl *ksl, ngtcp2_ksl_compar compar,
+ ngtcp2_ksl_search search, size_t keylen,
const ngtcp2_mem *mem) {
size_t nodelen = ksl_nodelen(keylen);
@@ -67,6 +68,7 @@ void ngtcp2_ksl_init(ngtcp2_ksl *ksl, ngtcp2_ksl_compar compar, size_t keylen,
ksl->head = NULL;
ksl->front = ksl->back = NULL;
ksl->compar = compar;
+ ksl->search = search;
ksl->n = 0;
ksl->keylen = keylen;
ksl->nodelen = nodelen;
@@ -269,19 +271,6 @@ static void ksl_insert_node(ngtcp2_ksl *ksl, ngtcp2_ksl_blk *blk, size_t i,
++blk->n;
}
-static size_t ksl_search(const ngtcp2_ksl *ksl, ngtcp2_ksl_blk *blk,
- const ngtcp2_ksl_key *key, ngtcp2_ksl_compar compar) {
- size_t i;
- ngtcp2_ksl_node *node;
-
- for (i = 0, node = (ngtcp2_ksl_node *)(void *)blk->nodes;
- i < blk->n && compar((ngtcp2_ksl_key *)node->key, key);
- ++i, node = (ngtcp2_ksl_node *)(void *)((uint8_t *)node + ksl->nodelen))
- ;
-
- return i;
-}
-
int ngtcp2_ksl_insert(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it,
const ngtcp2_ksl_key *key, void *data) {
ngtcp2_ksl_blk *blk;
@@ -306,7 +295,7 @@ int ngtcp2_ksl_insert(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it,
blk = ksl->head;
for (;;) {
- i = ksl_search(ksl, blk, key, ksl->compar);
+ i = ksl->search(ksl, blk, key);
if (blk->leaf) {
if (i < blk->n &&
@@ -565,7 +554,7 @@ int ngtcp2_ksl_remove(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it,
}
for (;;) {
- i = ksl_search(ksl, blk, key, ksl->compar);
+ i = ksl->search(ksl, blk, key);
if (i == blk->n) {
if (it) {
@@ -636,12 +625,12 @@ int ngtcp2_ksl_remove(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it,
ngtcp2_ksl_it ngtcp2_ksl_lower_bound(const ngtcp2_ksl *ksl,
const ngtcp2_ksl_key *key) {
- return ngtcp2_ksl_lower_bound_compar(ksl, key, ksl->compar);
+ return ngtcp2_ksl_lower_bound_search(ksl, key, ksl->search);
}
-ngtcp2_ksl_it ngtcp2_ksl_lower_bound_compar(const ngtcp2_ksl *ksl,
+ngtcp2_ksl_it ngtcp2_ksl_lower_bound_search(const ngtcp2_ksl *ksl,
const ngtcp2_ksl_key *key,
- ngtcp2_ksl_compar compar) {
+ ngtcp2_ksl_search search) {
ngtcp2_ksl_blk *blk = ksl->head;
ngtcp2_ksl_it it;
size_t i;
@@ -652,7 +641,7 @@ ngtcp2_ksl_it ngtcp2_ksl_lower_bound_compar(const ngtcp2_ksl *ksl,
}
for (;;) {
- i = ksl_search(ksl, blk, key, compar);
+ i = search(ksl, blk, key);
if (blk->leaf) {
if (i == blk->n && blk->next) {
@@ -696,7 +685,7 @@ void ngtcp2_ksl_update_key(ngtcp2_ksl *ksl, const ngtcp2_ksl_key *old_key,
assert(ksl->head);
for (;;) {
- i = ksl_search(ksl, blk, old_key, ksl->compar);
+ i = ksl->search(ksl, blk, old_key);
assert(i < blk->n);
node = ngtcp2_ksl_nth_node(ksl, blk, i);
@@ -819,9 +808,49 @@ int ngtcp2_ksl_range_compar(const ngtcp2_ksl_key *lhs,
return a->begin < b->begin;
}
+ngtcp2_ksl_search_def(range, ngtcp2_ksl_range_compar)
+
+size_t ngtcp2_ksl_range_search(const ngtcp2_ksl *ksl, ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key) {
+ return ksl_range_search(ksl, blk, key);
+}
+
int ngtcp2_ksl_range_exclusive_compar(const ngtcp2_ksl_key *lhs,
const ngtcp2_ksl_key *rhs) {
const ngtcp2_range *a = lhs, *b = rhs;
return a->begin < b->begin && !(ngtcp2_max_uint64(a->begin, b->begin) <
ngtcp2_min_uint64(a->end, b->end));
}
+
+ngtcp2_ksl_search_def(range_exclusive, ngtcp2_ksl_range_exclusive_compar)
+
+size_t ngtcp2_ksl_range_exclusive_search(const ngtcp2_ksl *ksl,
+ ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key) {
+ return ksl_range_exclusive_search(ksl, blk, key);
+}
+
+int ngtcp2_ksl_uint64_less(const ngtcp2_ksl_key *lhs,
+ const ngtcp2_ksl_key *rhs) {
+ return *(uint64_t *)lhs < *(uint64_t *)rhs;
+}
+
+ngtcp2_ksl_search_def(uint64_less, ngtcp2_ksl_uint64_less)
+
+size_t ngtcp2_ksl_uint64_less_search(const ngtcp2_ksl *ksl, ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key) {
+ return ksl_uint64_less_search(ksl, blk, key);
+}
+
+int ngtcp2_ksl_int64_greater(const ngtcp2_ksl_key *lhs,
+ const ngtcp2_ksl_key *rhs) {
+ return *(int64_t *)lhs > *(int64_t *)rhs;
+}
+
+ngtcp2_ksl_search_def(int64_greater, ngtcp2_ksl_int64_greater)
+
+size_t ngtcp2_ksl_int64_greater_search(const ngtcp2_ksl *ksl,
+ ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key) {
+ return ksl_int64_greater_search(ksl, blk, key);
+}
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h
index d8374b9b5..de78bcb80 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ksl.h
@@ -103,7 +103,7 @@ struct ngtcp2_ksl_blk {
};
};
-ngtcp2_objalloc_decl(ksl_blk, ngtcp2_ksl_blk, oplent);
+ngtcp2_objalloc_decl(ksl_blk, ngtcp2_ksl_blk, oplent)
/*
* ngtcp2_ksl_compar is a function type which returns nonzero if key
@@ -114,6 +114,33 @@ typedef int (*ngtcp2_ksl_compar)(const ngtcp2_ksl_key *lhs,
typedef struct ngtcp2_ksl ngtcp2_ksl;
+/*
+ * ngtcp2_ksl_search is a function to search for the first element in
+ * |blk|->nodes which is not ordered before |key|. It returns the
+ * index of such element. It returns |blk|->n if there is no such
+ * element.
+ */
+typedef size_t (*ngtcp2_ksl_search)(const ngtcp2_ksl *ksl, ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key);
+
+/*
+ * ngtcp2_ksl_search_def is a macro to implement ngtcp2_ksl_search
+ * with COMPAR which is supposed to be ngtcp2_ksl_compar.
+ */
+#define ngtcp2_ksl_search_def(NAME, COMPAR) \
+ static size_t ksl_##NAME##_search( \
+ const ngtcp2_ksl *ksl, ngtcp2_ksl_blk *blk, const ngtcp2_ksl_key *key) { \
+ size_t i; \
+ ngtcp2_ksl_node *node; \
+ \
+ for (i = 0, node = (ngtcp2_ksl_node *)(void *)blk->nodes; \
+ i < blk->n && COMPAR((ngtcp2_ksl_key *)node->key, key); ++i, \
+ node = (ngtcp2_ksl_node *)(void *)((uint8_t *)node + ksl->nodelen)) \
+ ; \
+ \
+ return i; \
+ }
+
typedef struct ngtcp2_ksl_it ngtcp2_ksl_it;
/*
@@ -137,6 +164,7 @@ struct ngtcp2_ksl {
/* back points to the last leaf block. */
ngtcp2_ksl_blk *back;
ngtcp2_ksl_compar compar;
+ ngtcp2_ksl_search search;
/* n is the number of elements stored. */
size_t n;
/* keylen is the size of key */
@@ -148,10 +176,12 @@ struct ngtcp2_ksl {
/*
* ngtcp2_ksl_init initializes |ksl|. |compar| specifies compare
- * function. |keylen| is the length of key and must be at least
+ * function. |search| is a search function which must use |compar|.
+ * |keylen| is the length of key and must be at least
* sizeof(uint64_t).
*/
-void ngtcp2_ksl_init(ngtcp2_ksl *ksl, ngtcp2_ksl_compar compar, size_t keylen,
+void ngtcp2_ksl_init(ngtcp2_ksl *ksl, ngtcp2_ksl_compar compar,
+ ngtcp2_ksl_search search, size_t keylen,
const ngtcp2_mem *mem);
/*
@@ -217,12 +247,12 @@ ngtcp2_ksl_it ngtcp2_ksl_lower_bound(const ngtcp2_ksl *ksl,
const ngtcp2_ksl_key *key);
/*
- * ngtcp2_ksl_lower_bound_compar works like ngtcp2_ksl_lower_bound,
- * but it takes custom function |compar| to do lower bound search.
+ * ngtcp2_ksl_lower_bound_search works like ngtcp2_ksl_lower_bound,
+ * but it takes custom function |search| to do lower bound search.
*/
-ngtcp2_ksl_it ngtcp2_ksl_lower_bound_compar(const ngtcp2_ksl *ksl,
+ngtcp2_ksl_it ngtcp2_ksl_lower_bound_search(const ngtcp2_ksl *ksl,
const ngtcp2_ksl_key *key,
- ngtcp2_ksl_compar compar);
+ ngtcp2_ksl_search search);
/*
* ngtcp2_ksl_update_key replaces the key of nodes which has |old_key|
@@ -329,21 +359,67 @@ int ngtcp2_ksl_it_begin(const ngtcp2_ksl_it *it);
/*
* ngtcp2_ksl_range_compar is an implementation of ngtcp2_ksl_compar.
- * lhs->ptr and rhs->ptr must point to ngtcp2_range object and the
- * function returns nonzero if (const ngtcp2_range *)(lhs->ptr)->begin
- * < (const ngtcp2_range *)(rhs->ptr)->begin.
+ * |lhs| and |rhs| must point to ngtcp2_range object, and the function
+ * returns nonzero if ((const ngtcp2_range *)lhs)->begin < ((const
+ * ngtcp2_range *)rhs)->begin.
*/
int ngtcp2_ksl_range_compar(const ngtcp2_ksl_key *lhs,
const ngtcp2_ksl_key *rhs);
/*
+ * ngtcp2_ksl_range_search is an implementation of ngtcp2_ksl_search
+ * that uses ngtcp2_ksl_range_compar.
+ */
+size_t ngtcp2_ksl_range_search(const ngtcp2_ksl *ksl, ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key);
+
+/*
* ngtcp2_ksl_range_exclusive_compar is an implementation of
- * ngtcp2_ksl_compar. lhs->ptr and rhs->ptr must point to
- * ngtcp2_range object and the function returns nonzero if (const
- * ngtcp2_range *)(lhs->ptr)->begin < (const ngtcp2_range
- * *)(rhs->ptr)->begin and the 2 ranges do not intersect.
+ * ngtcp2_ksl_compar. |lhs| and |rhs| must point to ngtcp2_range
+ * object, and the function returns nonzero if ((const ngtcp2_range
+ * *)lhs)->begin < ((const ngtcp2_range *)rhs)->begin, and the 2
+ * ranges do not intersect.
*/
int ngtcp2_ksl_range_exclusive_compar(const ngtcp2_ksl_key *lhs,
const ngtcp2_ksl_key *rhs);
+/*
+ * ngtcp2_ksl_range_exclusive_search is an implementation of
+ * ngtcp2_ksl_search that uses ngtcp2_ksl_range_exclusive_compar.
+ */
+size_t ngtcp2_ksl_range_exclusive_search(const ngtcp2_ksl *ksl,
+ ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key);
+
+/*
+ * ngtcp2_ksl_uint64_less is an implementation of ngtcp2_ksl_compar.
+ * |lhs| and |rhs| must point to uint64_t objects, and the function
+ * returns nonzero if *(uint64_t *)|lhs| < *(uint64_t *)|rhs|.
+ */
+int ngtcp2_ksl_uint64_less(const ngtcp2_ksl_key *lhs,
+ const ngtcp2_ksl_key *rhs);
+
+/*
+ * ngtcp2_ksl_uint64_less_search is an implementation of
+ * ngtcp2_ksl_search that uses ngtcp2_ksl_uint64_less.
+ */
+size_t ngtcp2_ksl_uint64_less_search(const ngtcp2_ksl *ksl, ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key);
+
+/*
+ * ngtcp2_ksl_int64_greater is an implementation of ngtcp2_ksl_compar.
+ * |lhs| and |rhs| must point to int64_t objects, and the function
+ * returns nonzero if *(int64_t *)|lhs| > *(int64_t *)|rhs|.
+ */
+int ngtcp2_ksl_int64_greater(const ngtcp2_ksl_key *lhs,
+ const ngtcp2_ksl_key *rhs);
+
+/*
+ * ngtcp2_ksl_int64_greater_search is an implementation of
+ * ngtcp2_ksl_search that uses ngtcp2_ksl_int64_greater.
+ */
+size_t ngtcp2_ksl_int64_greater_search(const ngtcp2_ksl *ksl,
+ ngtcp2_ksl_blk *blk,
+ const ngtcp2_ksl_key *key);
+
#endif /* !defined(NGTCP2_KSL_H) */
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h
index 649ed8434..dfe5e0aed 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h
@@ -55,27 +55,27 @@
#define ngtcp2_max_def(SUFFIX, T) \
static inline T ngtcp2_max_##SUFFIX(T a, T b) { return a < b ? b : a; }
-ngtcp2_max_def(int8, int8_t);
-ngtcp2_max_def(int16, int16_t);
-ngtcp2_max_def(int32, int32_t);
-ngtcp2_max_def(int64, int64_t);
-ngtcp2_max_def(uint8, uint8_t);
-ngtcp2_max_def(uint16, uint16_t);
-ngtcp2_max_def(uint32, uint32_t);
-ngtcp2_max_def(uint64, uint64_t);
-ngtcp2_max_def(size, size_t);
+ngtcp2_max_def(int8, int8_t)
+ngtcp2_max_def(int16, int16_t)
+ngtcp2_max_def(int32, int32_t)
+ngtcp2_max_def(int64, int64_t)
+ngtcp2_max_def(uint8, uint8_t)
+ngtcp2_max_def(uint16, uint16_t)
+ngtcp2_max_def(uint32, uint32_t)
+ngtcp2_max_def(uint64, uint64_t)
+ngtcp2_max_def(size, size_t)
#define ngtcp2_min_def(SUFFIX, T) \
static inline T ngtcp2_min_##SUFFIX(T a, T b) { return a < b ? a : b; }
-ngtcp2_min_def(int8, int8_t);
-ngtcp2_min_def(int16, int16_t);
-ngtcp2_min_def(int32, int32_t);
-ngtcp2_min_def(int64, int64_t);
-ngtcp2_min_def(uint8, uint8_t);
-ngtcp2_min_def(uint16, uint16_t);
-ngtcp2_min_def(uint32, uint32_t);
-ngtcp2_min_def(uint64, uint64_t);
-ngtcp2_min_def(size, size_t);
+ngtcp2_min_def(int8, int8_t)
+ngtcp2_min_def(int16, int16_t)
+ngtcp2_min_def(int32, int32_t)
+ngtcp2_min_def(int64, int64_t)
+ngtcp2_min_def(uint8, uint8_t)
+ngtcp2_min_def(uint16, uint16_t)
+ngtcp2_min_def(uint32, uint32_t)
+ngtcp2_min_def(uint64, uint64_t)
+ngtcp2_min_def(size, size_t)
#endif /* !defined(NGTCP2_MACRO_H) */
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.h
index 7ffa623d1..e9573da49 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pv.h
@@ -83,7 +83,7 @@ void ngtcp2_pv_entry_init(ngtcp2_pv_entry *pvent, const uint8_t *data,
typedef struct ngtcp2_pv ngtcp2_pv;
ngtcp2_static_ringbuf_def(pv_ents, NGTCP2_PV_MAX_ENTRIES,
- sizeof(ngtcp2_pv_entry));
+ sizeof(ngtcp2_pv_entry))
/*
* ngtcp2_pv is the context of a single path validation.
*/
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
index 1dab296a8..41446739b 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
@@ -31,18 +31,20 @@
#include "ngtcp2_macro.h"
+#ifndef NDEBUG
static int ispow2(size_t n) {
-#if defined(_MSC_VER) && !defined(__clang__) && \
- (defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941))
+# if defined(_MSC_VER) && !defined(__clang__) && \
+ (defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941))
return n && !(n & (n - 1));
-#elif defined(WIN32)
+# elif defined(WIN32)
return 1 == __popcnt((unsigned int)n);
-#else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
- (defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
+# else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
+ (defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
return 1 == __builtin_popcount((unsigned int)n);
-#endif /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
- (defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
+# endif /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
+ (defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
}
+#endif /* !defined(NDEBUG) */
int ngtcp2_ringbuf_init(ngtcp2_ringbuf *rb, size_t nmemb, size_t size,
const ngtcp2_mem *mem) {
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c
index 12c7d4097..ce6c2113d 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rob.c
@@ -68,8 +68,8 @@ int ngtcp2_rob_init(ngtcp2_rob *rob, size_t chunk, const ngtcp2_mem *mem) {
int rv;
ngtcp2_rob_gap *g;
- ngtcp2_ksl_init(&rob->gapksl, ngtcp2_ksl_range_compar, sizeof(ngtcp2_range),
- mem);
+ ngtcp2_ksl_init(&rob->gapksl, ngtcp2_ksl_range_compar,
+ ngtcp2_ksl_range_search, sizeof(ngtcp2_range), mem);
rv = ngtcp2_rob_gap_new(&g, 0, UINT64_MAX, mem);
if (rv != 0) {
@@ -81,8 +81,8 @@ int ngtcp2_rob_init(ngtcp2_rob *rob, size_t chunk, const ngtcp2_mem *mem) {
goto fail_gapksl_ksl_insert;
}
- ngtcp2_ksl_init(&rob->dataksl, ngtcp2_ksl_range_compar, sizeof(ngtcp2_range),
- mem);
+ ngtcp2_ksl_init(&rob->dataksl, ngtcp2_ksl_range_compar,
+ ngtcp2_ksl_range_search, sizeof(ngtcp2_range), mem);
rob->chunk = chunk;
rob->mem = mem;
@@ -125,8 +125,8 @@ static int rob_write_data(ngtcp2_rob *rob, uint64_t offset, const uint8_t *data,
ngtcp2_range range = {offset, offset + len};
ngtcp2_ksl_it it;
- for (it = ngtcp2_ksl_lower_bound_compar(&rob->dataksl, &range,
- ngtcp2_ksl_range_exclusive_compar);
+ for (it = ngtcp2_ksl_lower_bound_search(&rob->dataksl, &range,
+ ngtcp2_ksl_range_exclusive_search);
len; ngtcp2_ksl_it_next(&it)) {
if (ngtcp2_ksl_it_end(&it)) {
d = NULL;
@@ -166,8 +166,8 @@ int ngtcp2_rob_push(ngtcp2_rob *rob, uint64_t offset, const uint8_t *data,
ngtcp2_range m, l, r, q = {offset, offset + datalen};
ngtcp2_ksl_it it;
- it = ngtcp2_ksl_lower_bound_compar(&rob->gapksl, &q,
- ngtcp2_ksl_range_exclusive_compar);
+ it = ngtcp2_ksl_lower_bound_search(&rob->gapksl, &q,
+ ngtcp2_ksl_range_exclusive_search);
for (; !ngtcp2_ksl_it_end(&it);) {
g = ngtcp2_ksl_it_get(&it);
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c
index 008ba470c..4d417186e 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c
@@ -38,7 +38,7 @@
#include "ngtcp2_tstamp.h"
#include "ngtcp2_frame_chain.h"
-ngtcp2_objalloc_def(rtb_entry, ngtcp2_rtb_entry, oplent);
+ngtcp2_objalloc_def(rtb_entry, ngtcp2_rtb_entry, oplent)
static void rtb_entry_init(ngtcp2_rtb_entry *ent, const ngtcp2_pkt_hd *hd,
ngtcp2_frame_chain *frc, ngtcp2_tstamp ts,
@@ -81,17 +81,14 @@ void ngtcp2_rtb_entry_objalloc_del(ngtcp2_rtb_entry *ent,
ngtcp2_objalloc_rtb_entry_release(objalloc, ent);
}
-static int greater(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) {
- return *(int64_t *)lhs > *(int64_t *)rhs;
-}
-
void ngtcp2_rtb_init(ngtcp2_rtb *rtb, ngtcp2_rst *rst, ngtcp2_cc *cc,
int64_t cc_pkt_num, ngtcp2_log *log, ngtcp2_qlog *qlog,
ngtcp2_objalloc *rtb_entry_objalloc,
ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
rtb->rtb_entry_objalloc = rtb_entry_objalloc;
rtb->frc_objalloc = frc_objalloc;
- ngtcp2_ksl_init(&rtb->ents, greater, sizeof(int64_t), mem);
+ ngtcp2_ksl_init(&rtb->ents, ngtcp2_ksl_int64_greater,
+ ngtcp2_ksl_int64_greater_search, sizeof(int64_t), mem);
rtb->rst = rst;
rtb->cc = cc;
rtb->log = log;
@@ -870,7 +867,8 @@ ngtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr,
}
if (largest_pkt_sent_ts != UINT64_MAX && ack_eliciting_pkt_acked) {
- cc_ack.rtt = pkt_ts - largest_pkt_sent_ts;
+ cc_ack.rtt =
+ ngtcp2_max_uint64(pkt_ts - largest_pkt_sent_ts, NGTCP2_NANOSECONDS);
rv = ngtcp2_conn_update_rtt(conn, cc_ack.rtt, fr->ack_delay_unscaled, ts);
if (rv == 0 && cc->new_rtt_sample) {
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.h
index 768f4abc4..2ef772b2e 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.h
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.h
@@ -124,7 +124,7 @@ struct ngtcp2_rtb_entry {
};
};
-ngtcp2_objalloc_decl(rtb_entry, ngtcp2_rtb_entry, oplent);
+ngtcp2_objalloc_decl(rtb_entry, ngtcp2_rtb_entry, oplent)
/*
* ngtcp2_rtb_entry_objalloc_new allocates ngtcp2_rtb_entry object via
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c
index a30b05248..8ea969c4a 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c
@@ -32,10 +32,6 @@
#include "ngtcp2_vec.h"
#include "ngtcp2_frame_chain.h"
-static int offset_less(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) {
- return *(int64_t *)lhs < *(int64_t *)rhs;
-}
-
void ngtcp2_strm_init(ngtcp2_strm *strm, int64_t stream_id, uint32_t flags,
uint64_t max_rx_offset, uint64_t max_tx_offset,
void *stream_user_data, ngtcp2_objalloc *frc_objalloc,
@@ -180,7 +176,8 @@ static int strm_streamfrq_init(ngtcp2_strm *strm) {
return NGTCP2_ERR_NOMEM;
}
- ngtcp2_ksl_init(streamfrq, offset_less, sizeof(uint64_t), strm->mem);
+ ngtcp2_ksl_init(streamfrq, ngtcp2_ksl_uint64_less,
+ ngtcp2_ksl_uint64_less_search, sizeof(uint64_t), strm->mem);
strm->tx.streamfrq = streamfrq;
diff --git a/src/contrib/libngtcp2/ngtcp2/ngtcp2.h b/src/contrib/libngtcp2/ngtcp2/ngtcp2.h
index d9957752e..acc79be6e 100644
--- a/src/contrib/libngtcp2/ngtcp2/ngtcp2.h
+++ b/src/contrib/libngtcp2/ngtcp2/ngtcp2.h
@@ -1777,6 +1777,13 @@ typedef struct ngtcp2_settings {
* or :member:`ngtcp2_transport_params.initial_max_stream_data_uni`,
* depending on the type of stream. The window size is scaled up to
* the value specified in this field.
+ *
+ * Please note that the auto-tuning is done per stream. Even if the
+ * previous stream gets larger window as a result of auto-tuning,
+ * the new stream still starts with the initial value set in
+ * transport parameters. This might become a bottleneck if
+ * congestion window of a remote server is wide open. If this
+ * causes an issue, do not enable auto-tuning.
*/
uint64_t max_stream_window;
/**
diff --git a/src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h b/src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h
index 5b8626191..68093d18b 100644
--- a/src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h
+++ b/src/contrib/libngtcp2/ngtcp2/ngtcp2_crypto.h
@@ -39,6 +39,37 @@ extern "C" {
#endif /* defined(WIN32) */
/**
+ * @macrosection
+ *
+ * ngtcp2 crypto library error codes
+ */
+
+/**
+ * @macro
+ *
+ * :macro:`NGTCP2_CRYPTO_ERR_INTERNAL` indicates an internal error.
+ */
+#define NGTCP2_CRYPTO_ERR_INTERNAL -201
+
+/**
+ * @macro
+ *
+ * :macro:`NGTCP2_CRYPTO_ERR_UNREADABLE_TOKEN` indicates that a token
+ * is unreadable because it is not correctly formatted; or verifying
+ * the integrity protection failed.
+ */
+#define NGTCP2_CRYPTO_ERR_UNREADABLE_TOKEN -202
+
+/**
+ * @macro
+ *
+ * :macro:`NGTCP2_CRYPTO_ERR_VERIFY_TOKEN` indicates that a token does
+ * not probe the client address; or the token validity has expired; or
+ * it contains invalid Connection ID.
+ */
+#define NGTCP2_CRYPTO_ERR_VERIFY_TOKEN -203
+
+/**
* @function
*
* `ngtcp2_crypto_ctx_tls` initializes |ctx| by extracting negotiated
@@ -550,6 +581,14 @@ NGTCP2_EXTERN int ngtcp2_crypto_generate_stateless_reset_token(
/**
* @macro
*
+ * :macro:`NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY2` is the magic byte for
+ * Retry token generated by `ngtcp2_crypto_generate_retry_token2`.
+ */
+#define NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY2 0xb7
+
+/**
+ * @macro
+ *
* :macro:`NGTCP2_CRYPTO_TOKEN_MAGIC_REGULAR` is the magic byte for a
* token generated by `ngtcp2_crypto_generate_regular_token`.
*/
@@ -569,6 +608,17 @@ NGTCP2_EXTERN int ngtcp2_crypto_generate_stateless_reset_token(
/**
* @macro
*
+ * :macro:`NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN2` is the maximum length of
+ * a token generated by `ngtcp2_crypto_generate_retry_token2`.
+ */
+#define NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN2 \
+ (/* magic = */ 1 + sizeof(ngtcp2_sockaddr_union) + /* cid len = */ 1 + \
+ NGTCP2_MAX_CIDLEN + sizeof(ngtcp2_tstamp) + /* aead tag = */ 16 + \
+ NGTCP2_CRYPTO_TOKEN_RAND_DATALEN)
+
+/**
+ * @macro
+ *
* :macro:`NGTCP2_CRYPTO_MAX_REGULAR_TOKENLEN` is the maximum length
* of a token generated by `ngtcp2_crypto_generate_regular_token`.
*/
@@ -592,6 +642,8 @@ NGTCP2_EXTERN int ngtcp2_crypto_generate_stateless_reset_token(
* is a Destination Connection ID in Initial packet sent by client.
* |ts| is the timestamp when the token is generated.
*
+ * See also `ngtcp2_crypto_generate_retry_token2`.
+ *
* This function returns the length of generated token if it succeeds,
* or -1.
*/
@@ -627,6 +679,72 @@ NGTCP2_EXTERN int ngtcp2_crypto_verify_retry_token(
/**
* @function
*
+ * `ngtcp2_crypto_generate_retry_token2` generates a token in the
+ * buffer pointed by |token| that is sent with Retry packet. The
+ * buffer pointed by |token| must have at least
+ * :macro:`NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN2` bytes long. The
+ * successfully generated token starts with
+ * :macro:`NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY2`. |secret| of length
+ * |secretlen| is a keying material to generate keys to encrypt the
+ * token. |version| is QUIC version. |remote_addr| of length
+ * |remote_addrlen| is an address of client. |retry_scid| is a Source
+ * Connection ID chosen by server, and set in Retry packet. |odcid|
+ * is a Destination Connection ID in Initial packet sent by client.
+ * |ts| is the timestamp when the token is generated.
+ *
+ * Use this function instead of `ngtcp2_crypto_generate_retry_token`
+ * if more detailed error handling is required when verifying the
+ * token. `ngtcp2_crypto_verify_retry_token2` must be used to verify
+ * the token.
+ *
+ * This function returns the length of generated token if it succeeds,
+ * or -1.
+ */
+NGTCP2_EXTERN ngtcp2_ssize ngtcp2_crypto_generate_retry_token2(
+ uint8_t *token, const uint8_t *secret, size_t secretlen, uint32_t version,
+ const ngtcp2_sockaddr *remote_addr, ngtcp2_socklen remote_addrlen,
+ const ngtcp2_cid *retry_scid, const ngtcp2_cid *odcid, ngtcp2_tstamp ts);
+
+/**
+ * @function
+ *
+ * `ngtcp2_crypto_verify_retry_token2` verifies Retry token stored in
+ * the buffer pointed by |token| of length |tokenlen|. |secret| of
+ * length |secretlen| is a keying material to generate keys to decrypt
+ * the token. |version| is QUIC version of the Initial packet that
+ * contains this token. |remote_addr| of length |remote_addrlen| is
+ * an address of client. |dcid| is a Destination Connection ID in
+ * Initial packet sent by client. |timeout| is the period during
+ * which the token is valid. |ts| is the current timestamp. When
+ * validation succeeds, the extracted Destination Connection ID (which
+ * is the Destination Connection ID in Initial packet sent by client
+ * that triggered Retry packet) is stored in the buffer pointed by
+ * |odcid|.
+ *
+ * The token must be generated by
+ * `ngtcp2_crypto_generate_retry_token2`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :macro:`NGTCP2_CRYPTO_ERR_UNREADABLE_TOKEN`
+ * A token is badly formatted; or verifying the integrity
+ * protection failed.
+ * :macro:`NGTCP2_CRYPTO_ERR_VERIFY_TOKEN`
+ * A token does not probe the client address; or the token
+ * validity has expired; or it contains invalid Connection ID.
+ * :macro:`NGTCP2_CRYPTO_ERR_INTERNAL`
+ * Internal error occurred.
+ */
+NGTCP2_EXTERN int ngtcp2_crypto_verify_retry_token2(
+ ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen,
+ const uint8_t *secret, size_t secretlen, uint32_t version,
+ const ngtcp2_sockaddr *remote_addr, ngtcp2_socklen remote_addrlen,
+ const ngtcp2_cid *dcid, ngtcp2_duration timeout, ngtcp2_tstamp ts);
+
+/**
+ * @function
+ *
* `ngtcp2_crypto_generate_regular_token` generates a token in the
* buffer pointed by |token| that is sent with NEW_TOKEN frame. The
* buffer pointed by |token| must have at least
diff --git a/src/contrib/libngtcp2/ngtcp2/version.h b/src/contrib/libngtcp2/ngtcp2/version.h
index 881ecb114..15bf36ded 100644
--- a/src/contrib/libngtcp2/ngtcp2/version.h
+++ b/src/contrib/libngtcp2/ngtcp2/version.h
@@ -36,7 +36,7 @@
*
* Version number of the ngtcp2 library release.
*/
-#define NGTCP2_VERSION "1.8.1"
+#define NGTCP2_VERSION "1.9.0"
/**
* @macro
@@ -46,6 +46,6 @@
* number, 8 bits for minor and 8 bits for patch. Version 1.2.3
* becomes 0x010203.
*/
-#define NGTCP2_VERSION_NUM 0x010801
+#define NGTCP2_VERSION_NUM 0x010900
#endif /* !defined(NGTCP2_VERSION_H) */