From 8f63f6ff576150a05da4e071f786f5c0e04af280 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Wed, 31 Jan 2024 18:01:29 +0200 Subject: [PATCH] deps: update ngtcp2 to 1.2.0 PR-URL: https://github.com/nodejs/node/pull/51584 Reviewed-By: Marco Ippolito Reviewed-By: Antoine du Hamel --- .../ngtcp2/lib/includes/ngtcp2/ngtcp2.h | 17 +++++ .../ngtcp2/lib/includes/ngtcp2/version.h | 4 +- deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c | 3 + deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c | 74 ++++++------------- deps/ngtcp2/ngtcp2/lib/ngtcp2_log.c | 3 +- deps/ngtcp2/ngtcp2/lib/ngtcp2_net.h | 2 +- deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c | 6 +- deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h | 4 +- deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.c | 18 +++-- deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.h | 3 - deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.h | 2 +- deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c | 4 +- deps/ngtcp2/ngtcp2/lib/ngtcp2_strm.h | 4 + deps/ngtcp2/ngtcp2/lib/ngtcp2_window_filter.c | 21 +++++- 14 files changed, 91 insertions(+), 74 deletions(-) diff --git a/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/ngtcp2.h b/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/ngtcp2.h index f16d15cb39bb52..72c8142a5a5aa7 100644 --- a/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/ngtcp2.h +++ b/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/ngtcp2.h @@ -4269,6 +4269,9 @@ NGTCP2_EXTERN int ngtcp2_conn_open_uni_stream(ngtcp2_conn *conn, * * |flags| is currently unused, and should be set to 0. * + * This function returns 0 if a stream denoted by |stream_id| is not + * found. + * * This function returns 0 if it succeeds, or one of the following * negative error codes: * @@ -4291,6 +4294,9 @@ NGTCP2_EXTERN int ngtcp2_conn_shutdown_stream(ngtcp2_conn *conn, uint32_t flags, * * |flags| is currently unused, and should be set to 0. * + * This function returns 0 if a stream denoted by |stream_id| is not + * found. + * * This function returns 0 if it succeeds, or one of the following * negative error codes: * @@ -4315,6 +4321,9 @@ NGTCP2_EXTERN int ngtcp2_conn_shutdown_stream_write(ngtcp2_conn *conn, * * |flags| is currently unused, and should be set to 0. * + * This function returns 0 if a stream denoted by |stream_id| is not + * found. + * * This function returns 0 if it succeeds, or one of the following * negative error codes: * @@ -4675,6 +4684,9 @@ NGTCP2_EXTERN int ngtcp2_conn_in_draining_period(ngtcp2_conn *conn); * specifies the stream ID. This function only extends stream-level * flow control window. * + * This function returns 0 if a stream denoted by |stream_id| is not + * found. + * * This function returns 0 if it succeeds, or one of the following * negative error codes: * @@ -5340,6 +5352,11 @@ NGTCP2_EXTERN void ngtcp2_ccerr_set_application_error(ngtcp2_ccerr *ccerr, * CONNECTION_CLOSE (type 0x1d) frame. Otherwise, it does not produce * any data, and returns 0. * + * |destlen| could be shorten by some factors (e.g., server side + * amplification limit). This function returns + * :macro:`NGTCP2_ERR_NOBUF` if the resulting buffer is too small even + * if the given buffer has enough space. + * * This function must not be called from inside the callback * functions. * diff --git a/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/version.h b/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/version.h index 66a70ffe962964..b102eae8f9ec77 100644 --- a/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/version.h +++ b/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/version.h @@ -36,7 +36,7 @@ * * Version number of the ngtcp2 library release. */ -#define NGTCP2_VERSION "1.1.0" +#define NGTCP2_VERSION "1.2.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 0x010100 +#define NGTCP2_VERSION_NUM 0x010200 #endif /* VERSION_H */ diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c b/deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c index 6369887c28671b..ef311ff93c0feb 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_cc.c @@ -36,6 +36,7 @@ #include "ngtcp2_mem.h" #include "ngtcp2_rcvry.h" #include "ngtcp2_conn_stat.h" +#include "ngtcp2_unreachable.h" /* NGTCP2_CC_DELIVERY_RATE_SEC_FILTERLEN is the window length of delivery rate filter driven by ACK clocking. */ @@ -247,6 +248,8 @@ uint64_t ngtcp2_cbrt(uint64_t n) { # if defined(_WIN64) if (_BitScanReverse64(&index, n)) { d = 61 - index; + } else { + ngtcp2_unreachable(); } # else /* !defined(_WIN64) */ if (_BitScanReverse(&index, (unsigned int)(n >> 32))) { diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c b/deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c index f40ab5626109e9..a4873eb20c4b86 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c @@ -5329,7 +5329,6 @@ static int conn_recv_ack(ngtcp2_conn *conn, ngtcp2_pktns *pktns, ngtcp2_ack *fr, num_acked = ngtcp2_rtb_recv_ack(&pktns->rtb, fr, &conn->cstat, conn, pktns, pkt_ts, ts); if (num_acked < 0) { - /* TODO assert this */ assert(ngtcp2_err_is_fatal((int)num_acked)); return (int)num_acked; } @@ -5790,9 +5789,8 @@ static int conn_recv_path_response(ngtcp2_conn *conn, ngtcp2_path_response *fr, } if (!(pv->flags & NGTCP2_PV_FLAG_DONT_CARE)) { - if (!(pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE)) { + if (pv->dcid.seq != conn->dcid.current.seq) { assert(!conn->server); - assert(pv->dcid.seq != conn->dcid.current.seq); assert(conn->dcid.current.cid.datalen); rv = conn_retire_dcid(conn, &conn->dcid.current, ts); @@ -5871,25 +5869,6 @@ static int conn_recv_path_response(ngtcp2_conn *conn, ngtcp2_path_response *fr, return conn_stop_pv(conn, ts); } -/* - * pkt_num_bits returns the number of bits available when packet - * number is encoded in |pkt_numlen| bytes. - */ -static size_t pkt_num_bits(size_t pkt_numlen) { - switch (pkt_numlen) { - case 1: - return 8; - case 2: - return 16; - case 3: - return 24; - case 4: - return 32; - default: - ngtcp2_unreachable(); - } -} - /* * pktns_pkt_num_is_duplicate returns nonzero if |pkt_num| is * duplicated packet number. @@ -6020,9 +5999,7 @@ static int conn_verify_fixed_bit(ngtcp2_conn *conn, ngtcp2_pkt_hd *hd) { case NGTCP2_PKT_INITIAL: case NGTCP2_PKT_0RTT: case NGTCP2_PKT_HANDSHAKE: - /* TODO we cannot determine whether a token comes from NEW_TOKEN - frame or Retry packet. RFC 9287 requires that a token from - NEW_TOKEN. */ + /* RFC 9287 requires that a token from NEW_TOKEN. */ if (!(conn->flags & NGTCP2_CONN_FLAG_INITIAL_PKT_PROCESSED) && (conn->local.settings.token_type != NGTCP2_TOKEN_TYPE_NEW_TOKEN || !conn->local.settings.tokenlen)) { @@ -6145,7 +6122,8 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path, return NGTCP2_ERR_DISCARD_PKT; } - if (hd.type == NGTCP2_PKT_VERSION_NEGOTIATION) { + switch (hd.type) { + case NGTCP2_PKT_VERSION_NEGOTIATION: hdpktlen = (size_t)nread; ngtcp2_log_rx_pkt_hd(&conn->log, &hd); @@ -6181,7 +6159,7 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path, return NGTCP2_ERR_DISCARD_PKT; } return NGTCP2_ERR_RECV_VERSION_NEGOTIATION; - } else if (hd.type == NGTCP2_PKT_RETRY) { + case NGTCP2_PKT_RETRY: hdpktlen = (size_t)nread; ngtcp2_log_rx_pkt_hd(&conn->log, &hd); @@ -6402,10 +6380,7 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path, break; default: - /* unknown packet type */ - ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT, - "packet was ignored because of unknown packet type"); - return (ngtcp2_ssize)pktlen; + ngtcp2_unreachable(); } hp_mask = conn->callbacks.hp_mask; @@ -6438,7 +6413,7 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path, payloadlen = hd.len - hd.pkt_numlen; hd.pkt_num = ngtcp2_pkt_adjust_pkt_num(pktns->rx.max_pkt_num, hd.pkt_num, - pkt_num_bits(hd.pkt_numlen)); + hd.pkt_numlen); if (hd.pkt_num > NGTCP2_MAX_PKT_NUM) { ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT, "pkn=%" PRId64 " is greater than maximum pkn", hd.pkt_num); @@ -6624,14 +6599,8 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path, pktns_increase_ecn_counts(pktns, pi); - /* TODO Initial and Handshake are always acknowledged without - delay. */ - if (require_ack && - (++pktns->acktr.rx_npkt >= conn->local.settings.ack_thresh || - (pi->ecn & NGTCP2_ECN_MASK) == NGTCP2_ECN_CE)) { - ngtcp2_acktr_immediate_ack(&pktns->acktr); - } - + /* Initial and Handshake are always acknowledged without delay. No + need to call ngtcp2_acktr_immediate_ack(). */ rv = ngtcp2_conn_sched_ack(conn, &pktns->acktr, hd.pkt_num, require_ack, pkt_ts); if (rv != 0) { @@ -7057,7 +7026,7 @@ static int conn_recv_stream(ngtcp2_conn *conn, const ngtcp2_stream *fr) { if (strm == NULL) { return NGTCP2_ERR_NOMEM; } - /* TODO Perhaps, call new_stream callback? */ + rv = ngtcp2_conn_init_stream(conn, strm, fr->stream_id, NULL); if (rv != 0) { ngtcp2_objalloc_strm_release(&conn->strm_objalloc, strm); @@ -7464,7 +7433,7 @@ static int conn_recv_stop_sending(ngtcp2_conn *conn, return 0; } - /* Frame is received reset before we create ngtcp2_strm + /* STOP_SENDING frame is received before we create ngtcp2_strm object. */ strm = ngtcp2_objalloc_strm_get(&conn->strm_objalloc); if (strm == NULL) { @@ -7482,6 +7451,10 @@ static int conn_recv_stop_sending(ngtcp2_conn *conn, } } + if (strm->flags & NGTCP2_STRM_FLAG_STOP_SENDING_RECVED) { + return 0; + } + ngtcp2_strm_set_app_error_code(strm, fr->app_error_code); /* No RESET_STREAM is required if we have sent FIN and all data have @@ -7494,7 +7467,9 @@ static int conn_recv_stop_sending(ngtcp2_conn *conn, } } - strm->flags |= NGTCP2_STRM_FLAG_SHUT_WR | NGTCP2_STRM_FLAG_RESET_STREAM; + strm->flags |= NGTCP2_STRM_FLAG_SHUT_WR | + NGTCP2_STRM_FLAG_STOP_SENDING_RECVED | + NGTCP2_STRM_FLAG_RESET_STREAM; ngtcp2_strm_streamfrq_clear(strm); @@ -8751,12 +8726,8 @@ conn_recv_delayed_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_pkt_info *pi, pktns_increase_ecn_counts(pktns, pi); - if (require_ack && - (++pktns->acktr.rx_npkt >= conn->local.settings.ack_thresh || - (pi->ecn & NGTCP2_ECN_MASK) == NGTCP2_ECN_CE)) { - ngtcp2_acktr_immediate_ack(&pktns->acktr); - } - + /* Initial and Handshake are always acknowledged without delay. No + need to call ngtcp2_acktr_immediate_ack(). */ rv = ngtcp2_conn_sched_ack(conn, &pktns->acktr, hd->pkt_num, require_ack, pkt_ts); if (rv != 0) { @@ -9020,7 +8991,7 @@ static ngtcp2_ssize conn_recv_pkt(ngtcp2_conn *conn, const ngtcp2_path *path, payloadlen = pktlen - hdpktlen; hd.pkt_num = ngtcp2_pkt_adjust_pkt_num(pktns->rx.max_pkt_num, hd.pkt_num, - pkt_num_bits(hd.pkt_numlen)); + hd.pkt_numlen); if (hd.pkt_num > NGTCP2_MAX_PKT_NUM) { ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT, "pkn=%" PRId64 " is greater than maximum pkn", hd.pkt_num); @@ -12551,7 +12522,8 @@ static int conn_shutdown_stream_read(ngtcp2_conn *conn, ngtcp2_strm *strm, uint64_t app_error_code) { ngtcp2_strm_set_app_error_code(strm, app_error_code); - if (strm->flags & NGTCP2_STRM_FLAG_STOP_SENDING) { + if (strm->flags & + (NGTCP2_STRM_FLAG_STOP_SENDING | NGTCP2_STRM_FLAG_RESET_STREAM_RECVED)) { return 0; } if ((strm->flags & NGTCP2_STRM_FLAG_SHUT_RD) && diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_log.c b/deps/ngtcp2/ngtcp2/lib/ngtcp2_log.c index 760bd60a9aff76..93922a29c319f4 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_log.c +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_log.c @@ -68,8 +68,7 @@ void ngtcp2_log_init(ngtcp2_log *log, const ngtcp2_cid *scid, * Source Connection ID in hex string. * * : - * Event. pkt=packet, frm=frame, ldc=loss-detection, cry=crypto, - * con=connection(catch all) + * Event. See ngtcp2_log_event. * * # Frame event * diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_net.h b/deps/ngtcp2/ngtcp2/lib/ngtcp2_net.h index bf697927351851..4a2c4041d4d170 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_net.h +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_net.h @@ -87,7 +87,7 @@ #if defined(WIN32) /* Windows requires ws2_32 library for ntonl family functions. We define inline functions for those function so that we don't have - dependeny on that lib. */ + dependency on that lib. */ # ifdef _MSC_VER # define STIN static __inline diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c b/deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c index 12f7daeaf242a9..1687ff254d94c7 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.c @@ -558,7 +558,7 @@ ngtcp2_ssize ngtcp2_pkt_decode_stream_frame(ngtcp2_stream *dest, uint8_t type; size_t len = 1 + 1; const uint8_t *p; - size_t datalen; + size_t datalen = 0; size_t ndatalen = 0; size_t n; uint64_t vi; @@ -2139,9 +2139,9 @@ int ngtcp2_pkt_decode_retry(ngtcp2_pkt_retry *dest, const uint8_t *payload, } int64_t ngtcp2_pkt_adjust_pkt_num(int64_t max_pkt_num, int64_t pkt_num, - size_t n) { + size_t pkt_numlen) { int64_t expected = max_pkt_num + 1; - int64_t win = (int64_t)1 << n; + int64_t win = (int64_t)1 << (pkt_numlen * 8); int64_t hwin = win / 2; int64_t mask = win - 1; int64_t cand = (expected & ~mask) | pkt_num; diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h b/deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h index b1bec97c31a08c..feec4d32c97bdd 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_pkt.h @@ -1120,12 +1120,12 @@ ngtcp2_ssize ngtcp2_pkt_encode_datagram_frame(uint8_t *out, size_t outlen, /* * ngtcp2_pkt_adjust_pkt_num find the full 64 bits packet number for - * |pkt_num|, which is expected to be least significant |n| bits. The + * |pkt_num|, which is encoded in |pkt_numlen| bytes. The * |max_pkt_num| is the highest successfully authenticated packet * number. */ int64_t ngtcp2_pkt_adjust_pkt_num(int64_t max_pkt_num, int64_t pkt_num, - size_t n); + size_t pkt_numlen); /* * ngtcp2_pkt_validate_ack checks that ack is malformed or not. diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.c b/deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.c index ffba131e02b9a5..f7c122b1ab406b 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.c +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.c @@ -39,7 +39,6 @@ void ngtcp2_ppe_init(ngtcp2_ppe *ppe, uint8_t *out, size_t outlen, ppe->pkt_num_offset = 0; ppe->pkt_numlen = 0; ppe->pkt_num = 0; - ppe->sample_offset = 0; ppe->cc = cc; } @@ -69,8 +68,6 @@ int ngtcp2_ppe_encode_hd(ngtcp2_ppe *ppe, const ngtcp2_pkt_hd *hd) { return (int)rv; } - ppe->sample_offset = ppe->pkt_num_offset + 4; - buf->last += rv; ppe->pkt_numlen = hd->pkt_numlen; @@ -101,6 +98,14 @@ int ngtcp2_ppe_encode_frame(ngtcp2_ppe *ppe, ngtcp2_frame *fr) { return 0; } +/* + * ppe_sample_offset returns the offset to sample for packet number + * encryption. + */ +static size_t ppe_sample_offset(ngtcp2_ppe *ppe) { + return ppe->pkt_num_offset + 4; +} + ngtcp2_ssize ngtcp2_ppe_final(ngtcp2_ppe *ppe, const uint8_t **ppkt) { ngtcp2_buf *buf = &ppe->buf; ngtcp2_crypto_cc *cc = ppe->cc; @@ -132,9 +137,10 @@ ngtcp2_ssize ngtcp2_ppe_final(ngtcp2_ppe *ppe, const uint8_t **ppkt) { buf->last = payload + payloadlen + cc->aead.max_overhead; /* TODO Check that we have enough space to get sample */ - assert(ppe->sample_offset + NGTCP2_HP_SAMPLELEN <= ngtcp2_buf_len(buf)); + assert(ppe_sample_offset(ppe) + NGTCP2_HP_SAMPLELEN <= ngtcp2_buf_len(buf)); - rv = cc->hp_mask(mask, &cc->hp, &cc->hp_ctx, buf->begin + ppe->sample_offset); + rv = cc->hp_mask(mask, &cc->hp, &cc->hp_ctx, + buf->begin + ppe_sample_offset(ppe)); if (rv != 0) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -197,7 +203,7 @@ size_t ngtcp2_ppe_padding_hp_sample(ngtcp2_ppe *ppe) { assert(cc->aead.max_overhead); max_samplelen = - ngtcp2_buf_len(buf) + cc->aead.max_overhead - ppe->sample_offset; + ngtcp2_buf_len(buf) + cc->aead.max_overhead - ppe_sample_offset(ppe); if (max_samplelen < NGTCP2_HP_SAMPLELEN) { len = NGTCP2_HP_SAMPLELEN - max_samplelen; assert(ngtcp2_ppe_left(ppe) >= len); diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.h b/deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.h index bf220df37c14f2..2a069ef33451ab 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.h +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_ppe.h @@ -50,9 +50,6 @@ typedef struct ngtcp2_ppe { /* pkt_numlen is the number of bytes used to encode a packet number */ size_t pkt_numlen; - /* sample_offset is the offset to sample for packet number - encryption. */ - size_t sample_offset; /* pkt_num is the packet number written in buf. */ int64_t pkt_num; /* nonce is the buffer to store nonce. It should be equal or longer diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.h b/deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.h index 720c309f5adb5e..484c8f21f75de2 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.h +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_pq.h @@ -110,7 +110,7 @@ size_t ngtcp2_pq_size(ngtcp2_pq *pq); typedef int (*ngtcp2_pq_item_cb)(ngtcp2_pq_entry *item, void *arg); /* - * Applys |fun| to each item in |pq|. The |arg| is passed as arg + * 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. diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c b/deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c index b9e0139bddfcac..6308261369c382 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_rtb.c @@ -1006,7 +1006,9 @@ static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost, if (rtb_pkt_lost(rtb, cstat, ent, loss_delay, (size_t)pkt_thres, ts)) { /* All entries from ent are considered to be lost. */ latest_ts = oldest_ts = ent->ts; - last_lost_pkt_num = ent->hd.pkt_num; + /* +1 to pick this packet for persistent congestion in the + following loop. */ + last_lost_pkt_num = ent->hd.pkt_num + 1; max_ack_delay = conn->remote.transport_params ? conn->remote.transport_params->max_ack_delay : 0; diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_strm.h b/deps/ngtcp2/ngtcp2/lib/ngtcp2_strm.h index e8cc531f217ab1..223e38fc646b38 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_strm.h +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_strm.h @@ -81,6 +81,10 @@ typedef struct ngtcp2_frame_chain ngtcp2_frame_chain; /* NGTCP2_STRM_FLAG_SEND_RESET_STREAM is set when RESET_STREAM frame should be sent. */ #define NGTCP2_STRM_FLAG_SEND_RESET_STREAM 0x400u +/* NGTCP2_STRM_FLAG_STOP_SENDING_RECVED indicates that STOP_SENDING is + received from the remote endpoint. In this case, + NGTCP2_STRM_FLAG_SHUT_WR is also set. */ +#define NGTCP2_STRM_FLAG_STOP_SENDING_RECVED 0x800u typedef struct ngtcp2_strm ngtcp2_strm; diff --git a/deps/ngtcp2/ngtcp2/lib/ngtcp2_window_filter.c b/deps/ngtcp2/ngtcp2/lib/ngtcp2_window_filter.c index 71c816e4d3d815..39f3d408a741ba 100644 --- a/deps/ngtcp2/ngtcp2/lib/ngtcp2_window_filter.c +++ b/deps/ngtcp2/ngtcp2/lib/ngtcp2_window_filter.c @@ -39,12 +39,16 @@ void ngtcp2_window_filter_init(ngtcp2_window_filter *wf, uint64_t window_length) { wf->window_length = window_length; - memset(wf->estimates, 0, sizeof(wf->estimates)); + memset(wf->estimates, 0xff, sizeof(wf->estimates)); } void ngtcp2_window_filter_update(ngtcp2_window_filter *wf, uint64_t new_sample, uint64_t new_time) { - if (wf->estimates[0].sample == 0 || new_sample > wf->estimates[0].sample || + /* Reset all estimates if they have not yet been initialized, if new + sample is a new best, or if the newest recorded estimate is too + old. */ + if (wf->estimates[0].sample == UINT64_MAX || + new_sample > wf->estimates[0].sample || new_time - wf->estimates[2].time > wf->window_length) { ngtcp2_window_filter_reset(wf, new_sample, new_time); return; @@ -59,12 +63,19 @@ void ngtcp2_window_filter_update(ngtcp2_window_filter *wf, uint64_t new_sample, wf->estimates[2].time = new_time; } + /* Expire and update estimates as necessary. */ if (new_time - wf->estimates[0].time > wf->window_length) { + /* The best estimate hasn't been updated for an entire window, so + promote second and third best estimates. */ wf->estimates[0] = wf->estimates[1]; wf->estimates[1] = wf->estimates[2]; wf->estimates[2].sample = new_sample; wf->estimates[2].time = new_time; + /* Need to iterate one more time. Check if the new best estimate + is outside the window as well, since it may also have been + recorded a long time ago. Don't need to iterate once more + since we cover that case at the beginning of the method. */ if (new_time - wf->estimates[0].time > wf->window_length) { wf->estimates[0] = wf->estimates[1]; wf->estimates[1] = wf->estimates[2]; @@ -74,6 +85,9 @@ void ngtcp2_window_filter_update(ngtcp2_window_filter *wf, uint64_t new_sample, if (wf->estimates[1].sample == wf->estimates[0].sample && new_time - wf->estimates[1].time > wf->window_length >> 2) { + /* A quarter of the window has passed without a better sample, so + the second-best estimate is taken from the second quarter of + the window. */ wf->estimates[2].sample = new_sample; wf->estimates[2].time = new_time; wf->estimates[1] = wf->estimates[2]; @@ -82,6 +96,9 @@ void ngtcp2_window_filter_update(ngtcp2_window_filter *wf, uint64_t new_sample, if (wf->estimates[2].sample == wf->estimates[1].sample && new_time - wf->estimates[2].time > wf->window_length >> 1) { + /* We've passed a half of the window without a better estimate, so + take a third-best estimate from the second half of the + window. */ wf->estimates[2].sample = new_sample; wf->estimates[2].time = new_time; }