]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
contrib: upgrade embedded library ngtcp2 to v0.10.0
authorDaniel Salzman <daniel.salzman@nic.cz>
Thu, 20 Oct 2022 12:26:23 +0000 (14:26 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Thu, 20 Oct 2022 12:29:50 +0000 (14:29 +0200)
20 files changed:
Knot.files
configure.ac
doc/requirements.rst
src/contrib/Makefile.inc
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_addr.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr2.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_cc.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conv.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_log.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_macro.h
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pkt.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_pmtud.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_qlog.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_rtb.c
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c [new file with mode: 0644]
src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.h [new file with mode: 0644]
src/contrib/libngtcp2/ngtcp2/ngtcp2.h
src/contrib/libngtcp2/ngtcp2/version.h

index 2e3f95d086349e29f974ce6e786b38e44c09464f..88520e91be89c7f525adddf4e8f488119fdb1344 100644 (file)
@@ -140,6 +140,8 @@ src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.c
 src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.h
 src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c
 src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h
+src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c
+src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.h
 src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_vec.c
 src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_vec.h
 src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_version.c
index 63f3b2acf6d5d8f04ed62c6467f4d874f0a01e09..43b8b82171502294df0626e854b8f7662ffa1aef 100644 (file)
@@ -565,12 +565,12 @@ AS_IF([test "$enable_daemon" = "yes" -o "$enable_utilities" = "yes"], [
 
 # QUIC support
 AC_ARG_ENABLE([quic],
-   AS_HELP_STRING([--enable-quic=auto|yes|no], [Support DoQ (needs libngtcp2 >= 0.8.0, gnutls >= 3.7.2) [default=auto]]),
+   AS_HELP_STRING([--enable-quic=auto|yes|no], [Support DoQ (needs libngtcp2 >= 0.10.0, gnutls >= 3.7.2) [default=auto]]),
    [], [enable_quic=auto])
 
 AS_CASE([$enable_quic],
-   [auto], [PKG_CHECK_MODULES([libngtcp2], [libngtcp2 >= 0.8.0 libngtcp2_crypto_gnutls], [enable_quic=yes], [enable_quic=no])],
-   [yes], [PKG_CHECK_MODULES([libngtcp2], [libngtcp2 >= 0.8.0 libngtcp2_crypto_gnutls], [enable_quic=yes],
+   [auto], [PKG_CHECK_MODULES([libngtcp2], [libngtcp2 >= 0.10.0 libngtcp2_crypto_gnutls], [enable_quic=yes], [enable_quic=no])],
+   [yes], [PKG_CHECK_MODULES([libngtcp2], [libngtcp2 >= 0.10.0 libngtcp2_crypto_gnutls], [enable_quic=yes],
              AS_IF([test "$gnutls_quic" = "yes"],
                 [enable_quic=embedded
                  embedded_libngtcp2_CFLAGS="-I\$(top_srcdir)/src/contrib/libngtcp2 -I\$(top_srcdir)/src/contrib/libngtcp2/ngtcp2/lib"
index 6c1f77891fa5a5f76f67f51ec0690630c5bc6316..13d8187e0ba88bb2adad0af013774b0387ef156b 100644 (file)
@@ -110,6 +110,6 @@ recommendations.
 DNS-over-QUIC (DoQ) support in :doc:`knotd<man_knotd>`, :doc:`kxdpgun<man_kxdpgun>`,
 and :doc:`kdig<man_kdig>`:
 
-* libngtcp2 >= 0.8.0 (or embedded one via `--enable-quic`)
+* libngtcp2 >= 0.10.0 (or embedded one via `--enable-quic`)
 * gnutls >= 3.7.2
 * :ref:`Mode XDP` (for knotd and kxdpgun)
index c29112c3b6d691b669a72f0ffce36a638f27e2a5..fe376f26f4e47ea20847a2202e1d389ed624eedd 100644 (file)
@@ -252,6 +252,8 @@ libembngtcp2_la_SOURCES = \
        contrib/libngtcp2/ngtcp2/lib/ngtcp2_str.h \
        contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.c \
        contrib/libngtcp2/ngtcp2/lib/ngtcp2_strm.h \
+       contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c \
+       contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.h \
        contrib/libngtcp2/ngtcp2/lib/ngtcp2_vec.c \
        contrib/libngtcp2/ngtcp2/lib/ngtcp2_vec.h \
        contrib/libngtcp2/ngtcp2/lib/ngtcp2_version.c \
index daab5dd7ce664bf21d90710c67800c42bf642c6e..f389abe76d71c8e783cd844ac4ce2f2f213d7fe7 100644 (file)
@@ -27,6 +27,8 @@
 #include <string.h>
 #include <assert.h>
 
+#include "ngtcp2_unreachable.h"
+
 ngtcp2_addr *ngtcp2_addr_init(ngtcp2_addr *dest, const ngtcp2_sockaddr *addr,
                               ngtcp2_socklen addrlen) {
   dest->addrlen = addrlen;
@@ -66,8 +68,7 @@ static int sockaddr_eq(const ngtcp2_sockaddr *a, const ngtcp2_sockaddr *b) {
            memcmp(&ai->sin6_addr, &bi->sin6_addr, sizeof(ai->sin6_addr)) == 0;
   }
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 }
 
@@ -109,8 +110,7 @@ uint32_t ngtcp2_addr_compare(const ngtcp2_addr *aa, const ngtcp2_addr *bb) {
     return flags;
   }
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 }
 
index 0816d69b816c52316c0f3791fd92237ac5c61e79..ed26d3e092f8edbbb2a8768a6c6026740243cd0b 100644 (file)
@@ -34,8 +34,7 @@
 
 static const double pacing_gain_cycle[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1};
 
-#define NGTCP2_BBR_GAIN_CYCLELEN                                               \
-  (sizeof(pacing_gain_cycle) / sizeof(pacing_gain_cycle[0]))
+#define NGTCP2_BBR_GAIN_CYCLELEN ngtcp2_arraylen(pacing_gain_cycle)
 
 #define NGTCP2_BBR_HIGH_GAIN 2.89
 #define NGTCP2_BBR_PROBE_RTT_DURATION (200 * NGTCP2_MILLISECONDS)
@@ -201,7 +200,7 @@ void ngtcp2_cc_bbr_cc_on_persistent_congestion(ngtcp2_cc *ccx,
   cc->packet_conservation = 0;
 
   bbr_save_cwnd(cc, cstat);
-  cstat->cwnd = 2 * cstat->max_udp_payload_size;
+  cstat->cwnd = 2 * cstat->max_tx_udp_payload_size;
 }
 
 void ngtcp2_cc_bbr_cc_on_ack_recv(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
@@ -307,8 +306,9 @@ static void bbr_handle_recovery(ngtcp2_bbr_cc *cc, ngtcp2_conn_stat *cstat,
   if (cc->congestion_recovery_start_ts != UINT64_MAX) {
     cc->in_loss_recovery = 1;
     bbr_save_cwnd(cc, cstat);
-    cstat->cwnd = cstat->bytes_in_flight +
-                  ngtcp2_max(ack->bytes_delivered, cstat->max_udp_payload_size);
+    cstat->cwnd =
+        cstat->bytes_in_flight +
+        ngtcp2_max(ack->bytes_delivered, cstat->max_tx_udp_payload_size);
 
     cstat->congestion_recovery_start_ts = cc->congestion_recovery_start_ts;
     cc->congestion_recovery_start_ts = UINT64_MAX;
@@ -373,9 +373,9 @@ static void bbr_set_send_quantum(ngtcp2_bbr_cc *cc, ngtcp2_conn_stat *cstat) {
   (void)cc;
 
   if (cstat->pacing_rate < 1.2 * 1024 * 1024 / 8 / NGTCP2_SECONDS) {
-    cstat->send_quantum = cstat->max_udp_payload_size;
+    cstat->send_quantum = cstat->max_tx_udp_payload_size;
   } else if (cstat->pacing_rate < 24.0 * 1024 * 1024 / 8 / NGTCP2_SECONDS) {
-    cstat->send_quantum = cstat->max_udp_payload_size * 2;
+    cstat->send_quantum = cstat->max_tx_udp_payload_size * 2;
   } else {
     send_quantum =
         (uint64_t)(cstat->pacing_rate * (double)(cstat->min_rtt == UINT64_MAX
@@ -385,7 +385,7 @@ static void bbr_set_send_quantum(ngtcp2_bbr_cc *cc, ngtcp2_conn_stat *cstat) {
   }
 
   cstat->send_quantum =
-      ngtcp2_max(cstat->send_quantum, cstat->max_udp_payload_size * 10);
+      ngtcp2_max(cstat->send_quantum, cstat->max_tx_udp_payload_size * 10);
 }
 
 static uint64_t bbr_inflight(ngtcp2_bbr_cc *cc, ngtcp2_conn_stat *cstat,
@@ -413,9 +413,9 @@ static void bbr_modulate_cwnd_for_recovery(ngtcp2_bbr_cc *cc,
   if (ack->bytes_lost > 0) {
     if (cstat->cwnd > ack->bytes_lost) {
       cstat->cwnd -= ack->bytes_lost;
-      cstat->cwnd = ngtcp2_max(cstat->cwnd, 2 * cstat->max_udp_payload_size);
+      cstat->cwnd = ngtcp2_max(cstat->cwnd, 2 * cstat->max_tx_udp_payload_size);
     } else {
-      cstat->cwnd = cstat->max_udp_payload_size;
+      cstat->cwnd = 2 * cstat->max_tx_udp_payload_size;
     }
   }
 
@@ -446,7 +446,7 @@ static void bbr_modulate_cwnd_for_probe_rtt(ngtcp2_bbr_cc *cc,
                                             ngtcp2_conn_stat *cstat) {
   if (cc->state == NGTCP2_BBR_STATE_PROBE_RTT) {
     cstat->cwnd =
-        ngtcp2_min(cstat->cwnd, min_pipe_cwnd(cstat->max_udp_payload_size));
+        ngtcp2_min(cstat->cwnd, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
   }
 }
 
@@ -465,7 +465,7 @@ static void bbr_set_cwnd(ngtcp2_bbr_cc *cc, ngtcp2_conn_stat *cstat,
     }
 
     cstat->cwnd =
-        ngtcp2_max(cstat->cwnd, min_pipe_cwnd(cstat->max_udp_payload_size));
+        ngtcp2_max(cstat->cwnd, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
   }
 
   bbr_modulate_cwnd_for_probe_rtt(cc, cstat);
@@ -491,7 +491,7 @@ static void bbr_init(ngtcp2_bbr_cc *cc, ngtcp2_conn_stat *cstat,
   cc->congestion_recovery_next_round_delivered = 0;
   cc->in_loss_recovery = 0;
 
-  cstat->send_quantum = cstat->max_udp_payload_size * 10;
+  cstat->send_quantum = cstat->max_tx_udp_payload_size * 10;
 
   ngtcp2_window_filter_init(&cc->btl_bw_filter, NGTCP2_BBR_BTL_BW_FILTERLEN);
 
@@ -654,7 +654,7 @@ static void bbr_handle_probe_rtt(ngtcp2_bbr_cc *cc, ngtcp2_conn_stat *cstat,
   cc->rst->app_limited = app_limited ? app_limited : 1;
 
   if (cc->probe_rtt_done_stamp == UINT64_MAX &&
-      cstat->bytes_in_flight <= min_pipe_cwnd(cstat->max_udp_payload_size)) {
+      cstat->bytes_in_flight <= min_pipe_cwnd(cstat->max_tx_udp_payload_size)) {
     cc->probe_rtt_done_stamp = ts + NGTCP2_BBR_PROBE_RTT_DURATION;
     cc->probe_rtt_round_done = 0;
     cc->next_round_delivered = cc->rst->delivered;
index 585ea11e8e29a574f544033686d26bdbcd07d1a7..baf4b4640acee5436c99f550955a927ff5b39b6b 100644 (file)
@@ -295,7 +295,7 @@ static void bbr_on_init(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
   bbr_init_pacing_rate(bbr, cstat);
   bbr_enter_startup(bbr);
 
-  cstat->send_quantum = cstat->max_udp_payload_size * 10;
+  cstat->send_quantum = cstat->max_tx_udp_payload_size * 10;
 
   /* Missing in documentation */
   bbr->loss_round_start = 0;
@@ -798,10 +798,10 @@ static uint64_t bbr_inflight_with_headroom(ngtcp2_bbr2_cc *bbr,
     return UINT64_MAX;
   }
 
-  headroom = ngtcp2_max(cstat->max_udp_payload_size,
+  headroom = ngtcp2_max(cstat->max_tx_udp_payload_size,
                         bbr->inflight_hi * NGTCP2_BBR_HEADROOM_NUMER /
                             NGTCP2_BBR_HEADROOM_DENOM);
-  mpcwnd = min_pipe_cwnd(cstat->max_udp_payload_size);
+  mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
 
   if (bbr->inflight_hi > headroom) {
     return ngtcp2_max(bbr->inflight_hi - headroom, mpcwnd);
@@ -812,12 +812,12 @@ static uint64_t bbr_inflight_with_headroom(ngtcp2_bbr2_cc *bbr,
 
 static void bbr_raise_inflight_hi_slope(ngtcp2_bbr2_cc *bbr,
                                         ngtcp2_conn_stat *cstat) {
-  uint64_t growth_this_round = cstat->max_udp_payload_size
+  uint64_t growth_this_round = cstat->max_tx_udp_payload_size
                                << bbr->bw_probe_up_rounds;
 
   bbr->bw_probe_up_rounds = ngtcp2_min(bbr->bw_probe_up_rounds + 1, 30);
   bbr->probe_up_cnt = ngtcp2_max(cstat->cwnd / growth_this_round, 1) *
-                      cstat->max_udp_payload_size;
+                      cstat->max_tx_udp_payload_size;
 }
 
 static void bbr_probe_inflight_hi_upward(ngtcp2_bbr2_cc *bbr,
@@ -834,7 +834,7 @@ static void bbr_probe_inflight_hi_upward(ngtcp2_bbr2_cc *bbr,
   if (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->inflight_hi += delta * cstat->max_udp_payload_size;
+    bbr->inflight_hi += delta * cstat->max_tx_udp_payload_size;
   }
 
   if (bbr->round_start) {
@@ -905,7 +905,7 @@ static void bbr_pick_probe_wait(ngtcp2_bbr2_cc *bbr) {
 static int bbr_is_reno_coexistence_probe_time(ngtcp2_bbr2_cc *bbr,
                                               ngtcp2_conn_stat *cstat) {
   uint64_t reno_rounds =
-      bbr_target_inflight(bbr, cstat) / cstat->max_udp_payload_size;
+      bbr_target_inflight(bbr, cstat) / cstat->max_tx_udp_payload_size;
 
   return bbr->rounds_since_bw_probe >= ngtcp2_min(reno_rounds, 63);
 }
@@ -1097,7 +1097,7 @@ static void bbr_mark_connection_app_limited(ngtcp2_bbr2_cc *bbr,
   if (app_limited) {
     bbr->rst->app_limited = app_limited;
   } else {
-    bbr->rst->app_limited = cstat->max_udp_payload_size;
+    bbr->rst->app_limited = cstat->max_tx_udp_payload_size;
   }
 }
 
@@ -1153,10 +1153,11 @@ static uint64_t bbr_quantization_budget(ngtcp2_bbr2_cc *bbr,
   bbr_update_offload_budget(bbr, cstat);
 
   inflight = ngtcp2_max(inflight, bbr->offload_budget);
-  inflight = ngtcp2_max(inflight, min_pipe_cwnd(cstat->max_udp_payload_size));
+  inflight =
+      ngtcp2_max(inflight, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
 
   if (bbr->state == NGTCP2_BBR2_STATE_PROBE_BW_UP) {
-    inflight += 2 * cstat->max_udp_payload_size;
+    inflight += 2 * cstat->max_tx_udp_payload_size;
   }
 
   return inflight;
@@ -1195,9 +1196,9 @@ static void bbr_modulate_cwnd_for_recovery(ngtcp2_bbr2_cc *bbr,
   if (ack->bytes_lost > 0) {
     if (cstat->cwnd > ack->bytes_lost) {
       cstat->cwnd -= ack->bytes_lost;
-      cstat->cwnd = ngtcp2_max(cstat->cwnd, 2 * cstat->max_udp_payload_size);
+      cstat->cwnd = ngtcp2_max(cstat->cwnd, 2 * cstat->max_tx_udp_payload_size);
     } else {
-      cstat->cwnd = cstat->max_udp_payload_size;
+      cstat->cwnd = 2 * cstat->max_tx_udp_payload_size;
     }
   }
 
@@ -1224,7 +1225,7 @@ static uint64_t bbr_probe_rtt_cwnd(ngtcp2_bbr2_cc *bbr,
                                    ngtcp2_conn_stat *cstat) {
   uint64_t probe_rtt_cwnd =
       bbr_bdp_multiple(bbr, bbr->bw, NGTCP2_BBR_PROBE_RTT_CWND_GAIN);
-  uint64_t mpcwnd = min_pipe_cwnd(cstat->max_udp_payload_size);
+  uint64_t mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
 
   return ngtcp2_max(probe_rtt_cwnd, mpcwnd);
 }
@@ -1256,7 +1257,7 @@ static void bbr_set_cwnd(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
       cstat->cwnd += ack->bytes_delivered;
     }
 
-    mpcwnd = min_pipe_cwnd(cstat->max_udp_payload_size);
+    mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
     cstat->cwnd = ngtcp2_max(cstat->cwnd, mpcwnd);
   }
 
@@ -1267,7 +1268,7 @@ static void bbr_set_cwnd(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
 static void bbr_bound_cwnd_for_model(ngtcp2_bbr2_cc *bbr,
                                      ngtcp2_conn_stat *cstat) {
   uint64_t cap = UINT64_MAX;
-  uint64_t mpcwnd = min_pipe_cwnd(cstat->max_udp_payload_size);
+  uint64_t mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
 
   if (bbr_is_in_probe_bw_state(bbr) &&
       bbr->state != NGTCP2_BBR2_STATE_PROBE_BW_CRUISE) {
@@ -1292,7 +1293,7 @@ static void bbr_set_send_quantum(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat) {
 
   cstat->send_quantum = ngtcp2_min(send_quantum, 64 * 1024);
   cstat->send_quantum =
-      ngtcp2_max(cstat->send_quantum, cstat->max_udp_payload_size * 10);
+      ngtcp2_max(cstat->send_quantum, cstat->max_tx_udp_payload_size * 10);
 }
 
 static int in_congestion_recovery(const ngtcp2_conn_stat *cstat,
@@ -1320,8 +1321,9 @@ static void bbr_handle_recovery(ngtcp2_bbr2_cc *bbr, ngtcp2_conn_stat *cstat,
   if (bbr->congestion_recovery_start_ts != UINT64_MAX) {
     bbr->in_loss_recovery = 1;
     bbr_save_cwnd(bbr, cstat);
-    cstat->cwnd = cstat->bytes_in_flight +
-                  ngtcp2_max(ack->bytes_delivered, cstat->max_udp_payload_size);
+    cstat->cwnd =
+        cstat->bytes_in_flight +
+        ngtcp2_max(ack->bytes_delivered, cstat->max_tx_udp_payload_size);
 
     cstat->congestion_recovery_start_ts = bbr->congestion_recovery_start_ts;
     bbr->congestion_recovery_start_ts = UINT64_MAX;
@@ -1408,9 +1410,9 @@ static void bbr2_cc_on_persistent_congestion(ngtcp2_cc *ccx,
   bbr->packet_conservation = 0;
 
   bbr_save_cwnd(bbr, cstat);
-  cstat->cwnd = cstat->bytes_in_flight + cstat->max_udp_payload_size;
+  cstat->cwnd = cstat->bytes_in_flight + cstat->max_tx_udp_payload_size;
   cstat->cwnd =
-      ngtcp2_max(cstat->cwnd, min_pipe_cwnd(cstat->max_udp_payload_size));
+      ngtcp2_max(cstat->cwnd, min_pipe_cwnd(cstat->max_tx_udp_payload_size));
 }
 
 static void bbr2_cc_on_ack_recv(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
index 5db484ef8c11ae7b33a182fc300d98677a99b1f5..0536639a15de6eed5c0accd20174a99bf8152b83 100644 (file)
@@ -126,7 +126,7 @@ void ngtcp2_cc_reno_cc_on_pkt_acked(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
     return;
   }
 
-  m = cstat->max_udp_payload_size * pkt->pktlen + cc->pending_add;
+  m = cstat->max_tx_udp_payload_size * pkt->pktlen + cc->pending_add;
   cc->pending_add = m % cstat->cwnd;
 
   cstat->cwnd += m / cstat->cwnd;
@@ -144,7 +144,7 @@ void ngtcp2_cc_reno_cc_congestion_event(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
 
   cstat->congestion_recovery_start_ts = ts;
   cstat->cwnd >>= NGTCP2_LOSS_REDUCTION_FACTOR_BITS;
-  min_cwnd = 2 * cstat->max_udp_payload_size;
+  min_cwnd = 2 * cstat->max_tx_udp_payload_size;
   cstat->cwnd = ngtcp2_max(cstat->cwnd, min_cwnd);
   cstat->ssthresh = cstat->cwnd;
 
@@ -161,7 +161,7 @@ void ngtcp2_cc_reno_cc_on_persistent_congestion(ngtcp2_cc *ccx,
   (void)ccx;
   (void)ts;
 
-  cstat->cwnd = 2 * cstat->max_udp_payload_size;
+  cstat->cwnd = 2 * cstat->max_tx_udp_payload_size;
   cstat->congestion_recovery_start_ts = UINT64_MAX;
 }
 
@@ -179,7 +179,7 @@ void ngtcp2_cc_reno_cc_on_ack_recv(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
 
   if (cstat->min_rtt != UINT64_MAX && cc->max_delivery_rate_sec) {
     target_cwnd = cc->max_delivery_rate_sec * cstat->min_rtt / NGTCP2_SECONDS;
-    initcwnd = ngtcp2_cc_compute_initcwnd(cstat->max_udp_payload_size);
+    initcwnd = ngtcp2_cc_compute_initcwnd(cstat->max_tx_udp_payload_size);
     cc->target_cwnd = ngtcp2_max(initcwnd, target_cwnd) * 289 / 100;
 
     ngtcp2_log_info(cc->ccb.log, NGTCP2_LOG_EVENT_RCV,
@@ -336,7 +336,8 @@ void ngtcp2_cc_cubic_cc_on_pkt_acked(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
 
     if (cc->last_round_min_rtt != UINT64_MAX &&
         cc->current_round_min_rtt != UINT64_MAX &&
-        cstat->cwnd >= NGTCP2_HS_MIN_SSTHRESH * cstat->max_udp_payload_size &&
+        cstat->cwnd >=
+            NGTCP2_HS_MIN_SSTHRESH * cstat->max_tx_udp_payload_size &&
         cc->rtt_sample_count >= NGTCP2_HS_N_RTT_SAMPLE) {
       eta = cc->last_round_min_rtt / 8;
 
@@ -364,7 +365,7 @@ void ngtcp2_cc_cubic_cc_on_pkt_acked(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
     cc->epoch_start = ts;
     if (cstat->cwnd < cc->w_last_max) {
       cc->k = ngtcp2_cbrt((cc->w_last_max - cstat->cwnd) * 10 / 4 /
-                          cstat->max_udp_payload_size);
+                          cstat->max_tx_udp_payload_size);
       cc->origin_point = cc->w_last_max;
     } else {
       cc->k = 0;
@@ -393,7 +394,7 @@ void ngtcp2_cc_cubic_cc_on_pkt_acked(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
     time_delta = kx - tx;
   }
 
-  delta = cstat->max_udp_payload_size *
+  delta = cstat->max_tx_udp_payload_size *
           ((((time_delta * time_delta) >> 10) * time_delta) >> 10) * 4 / 10;
   delta >>= 10;
 
@@ -414,23 +415,24 @@ void ngtcp2_cc_cubic_cc_on_pkt_acked(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
   }
 
   if (target > cstat->cwnd) {
-    m = cc->pending_add + cstat->max_udp_payload_size * (target - cstat->cwnd);
+    m = cc->pending_add +
+        cstat->max_tx_udp_payload_size * (target - cstat->cwnd);
     add = m / cstat->cwnd;
     cc->pending_add = m % cstat->cwnd;
   } else {
-    m = cc->pending_add + cstat->max_udp_payload_size;
+    m = cc->pending_add + cstat->max_tx_udp_payload_size;
     add = m / (100 * cstat->cwnd);
     cc->pending_add = m % (100 * cstat->cwnd);
   }
 
-  m = cc->pending_w_add + cstat->max_udp_payload_size * pkt->pktlen;
+  m = cc->pending_w_add + cstat->max_tx_udp_payload_size * pkt->pktlen;
 
   cc->w_tcp += m / cstat->cwnd;
   cc->pending_w_add = m % cstat->cwnd;
 
   if (cc->w_tcp > cstat->cwnd) {
-    tcp_add =
-        cstat->max_udp_payload_size * (cc->w_tcp - cstat->cwnd) / cstat->cwnd;
+    tcp_add = cstat->max_tx_udp_payload_size * (cc->w_tcp - cstat->cwnd) /
+              cstat->cwnd;
     if (tcp_add > add) {
       add = tcp_add;
     }
@@ -476,7 +478,7 @@ void ngtcp2_cc_cubic_cc_congestion_event(ngtcp2_cc *ccx,
     cc->w_last_max = cstat->cwnd;
   }
 
-  min_cwnd = 2 * cstat->max_udp_payload_size;
+  min_cwnd = 2 * cstat->max_tx_udp_payload_size;
   cstat->ssthresh = cstat->cwnd * 7 / 10;
   cstat->ssthresh = ngtcp2_max(cstat->ssthresh, min_cwnd);
   cstat->cwnd = cstat->ssthresh;
@@ -526,7 +528,7 @@ void ngtcp2_cc_cubic_cc_on_persistent_congestion(ngtcp2_cc *ccx,
   (void)ccx;
   (void)ts;
 
-  cstat->cwnd = 2 * cstat->max_udp_payload_size;
+  cstat->cwnd = 2 * cstat->max_tx_udp_payload_size;
   cstat->congestion_recovery_start_ts = UINT64_MAX;
 }
 
@@ -545,7 +547,7 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
 
   if (cstat->min_rtt != UINT64_MAX && cc->max_delivery_rate_sec) {
     target_cwnd = cc->max_delivery_rate_sec * cstat->min_rtt / NGTCP2_SECONDS;
-    initcwnd = ngtcp2_cc_compute_initcwnd(cstat->max_udp_payload_size);
+    initcwnd = ngtcp2_cc_compute_initcwnd(cstat->max_tx_udp_payload_size);
     cc->target_cwnd = ngtcp2_max(initcwnd, target_cwnd) * 289 / 100;
 
     ngtcp2_log_info(cc->ccb.log, NGTCP2_LOG_EVENT_RCV,
index 867c25405d9986abba41af8e1032ba36681dbd3b..128035849a1f15c73952a31df1e64e54d12d198a 100644 (file)
@@ -35,6 +35,7 @@
 #include "ngtcp2_addr.h"
 #include "ngtcp2_path.h"
 #include "ngtcp2_rcvry.h"
+#include "ngtcp2_unreachable.h"
 
 /* NGTCP2_FLOW_WINDOW_RTT_FACTOR is the factor of RTT when flow
    control window auto-tuning is triggered. */
@@ -810,7 +811,7 @@ static void conn_reset_conn_stat_cc(ngtcp2_conn *conn,
   cstat->pto_count = 0;
   cstat->loss_detection_timer = UINT64_MAX;
   cstat->cwnd =
-      ngtcp2_cc_compute_initcwnd(conn->local.settings.max_udp_payload_size);
+      ngtcp2_cc_compute_initcwnd(conn->local.settings.max_tx_udp_payload_size);
   cstat->ssthresh = UINT64_MAX;
   cstat->congestion_recovery_start_ts = UINT64_MAX;
   cstat->bytes_in_flight = 0;
@@ -959,7 +960,7 @@ static void conn_handle_tx_ecn(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
   case NGTCP2_ECN_STATE_FAILED:
     break;
   default:
-    assert(0);
+    ngtcp2_unreachable();
   }
 }
 
@@ -1065,8 +1066,8 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
 
   assert(settings->max_window <= NGTCP2_MAX_VARINT);
   assert(settings->max_stream_window <= NGTCP2_MAX_VARINT);
-  assert(settings->max_udp_payload_size);
-  assert(settings->max_udp_payload_size <= NGTCP2_HARD_MAX_UDP_PAYLOAD_SIZE);
+  assert(settings->max_tx_udp_payload_size);
+  assert(settings->max_tx_udp_payload_size <= NGTCP2_HARD_MAX_UDP_PAYLOAD_SIZE);
   assert(params->active_connection_id_limit <= NGTCP2_MAX_DCID_POOL_SIZE);
   assert(params->initial_max_data <= NGTCP2_MAX_VARINT);
   assert(params->initial_max_stream_data_bidi_local <= NGTCP2_MAX_VARINT);
@@ -1157,8 +1158,8 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
 
   conn_reset_conn_stat(*pconn, &(*pconn)->cstat);
   (*pconn)->cstat.initial_rtt = settings->initial_rtt;
-  (*pconn)->cstat.max_udp_payload_size =
-      (*pconn)->local.settings.max_udp_payload_size;
+  (*pconn)->cstat.max_tx_udp_payload_size =
+      (*pconn)->local.settings.max_tx_udp_payload_size;
 
   ngtcp2_rst_init(&(*pconn)->rst);
 
@@ -1194,7 +1195,7 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
     }
     break;
   default:
-    assert(0);
+    ngtcp2_unreachable();
   }
 
   rv = pktns_new(&(*pconn)->in_pktns, NGTCP2_PKTNS_ID_INITIAL, &(*pconn)->rst,
@@ -1888,7 +1889,7 @@ static size_t pktns_select_pkt_numlen(ngtcp2_pktns *pktns) {
  */
 static uint64_t conn_get_cwnd(ngtcp2_conn *conn) {
   return conn->pv && (conn->pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE)
-             ? ngtcp2_cc_compute_initcwnd(conn->cstat.max_udp_payload_size)
+             ? ngtcp2_cc_compute_initcwnd(conn->cstat.max_tx_udp_payload_size)
              : conn->cstat.cwnd;
 }
 
@@ -2590,8 +2591,7 @@ conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
     cc.hp_ctx = pktns->crypto.tx.hp_ctx;
     break;
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 
   cc.aead = pktns->crypto.ctx.aead;
@@ -2673,7 +2673,7 @@ conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
 
       rv = conn_ppe_write_frame_hd_log(conn, &ppe, &hd_logged, &hd, &nfrc->fr);
       if (rv != 0) {
-        assert(0);
+        ngtcp2_unreachable();
       }
 
       *pfrc = nfrc;
@@ -2872,8 +2872,7 @@ static ngtcp2_ssize conn_write_ack_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
     ack_delay_exponent = conn->local.transport_params.ack_delay_exponent;
     break;
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 
   if (!pktns->crypto.tx.ckm) {
@@ -2992,11 +2991,11 @@ static ngtcp2_ssize conn_write_handshake_ack_pkts(ngtcp2_conn *conn,
   ngtcp2_ssize res = 0, nwrite = 0;
 
   /* In the most cases, client sends ACK in conn_write_handshake_pkt.
-     This function is only called when it is CWND limited.  It is not
-     required for client to send ACK for server Initial.  This is
-     because once it gets server Initial, it gets Handshake tx key and
-     discards Initial key.  The only good reason to send ACK is give
-     server RTT measurement early. */
+     This function is only called when it is CWND limited or pacing
+     limited.  It is not required for client to send ACK for server
+     Initial.  This is because once it gets server Initial, it gets
+     Handshake tx key and discards Initial key.  The only good reason
+     to send ACK is give server RTT measurement early. */
   if (conn->server && conn->in_pktns) {
     nwrite =
         conn_write_ack_pkt(conn, pi, dest, destlen, NGTCP2_PKT_INITIAL, ts);
@@ -3574,7 +3573,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
       break;
     default:
       /* Unreachable */
-      assert(0);
+      ngtcp2_unreachable();
     }
 
     cc->encrypt = conn->callbacks.encrypt;
@@ -3717,8 +3716,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
 
         break;
       case NGTCP2_FRAME_STREAM:
-        assert(0);
-        break;
+        ngtcp2_unreachable();
       case NGTCP2_FRAME_MAX_STREAMS_BIDI:
         if ((*pfrc)->fr.max_streams.max_streams <
             conn->remote.bidi.max_streams) {
@@ -3757,8 +3755,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
         }
         break;
       case NGTCP2_FRAME_CRYPTO:
-        assert(0);
-        break;
+        ngtcp2_unreachable();
       }
 
       rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &(*pfrc)->fr);
@@ -3802,7 +3799,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
 
         rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &nfrc->fr);
         if (rv != 0) {
-          assert(0);
+          ngtcp2_unreachable();
         }
 
         *pfrc = nfrc;
@@ -3976,7 +3973,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
 
         rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &nfrc->fr);
         if (rv != 0) {
-          assert(0);
+          ngtcp2_unreachable();
         }
 
         *pfrc = nfrc;
@@ -4068,7 +4065,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
 
     rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &nfrc->fr);
     if (rv != 0) {
-      assert(0);
+      ngtcp2_unreachable();
     }
 
     *pfrc = nfrc;
@@ -4178,7 +4175,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
          calls ngtcp2_conn_writev_datagram again. */
       break;
     default:
-      assert(0);
+      ngtcp2_unreachable();
     }
   }
 
@@ -4360,8 +4357,7 @@ ngtcp2_ssize ngtcp2_conn_write_single_frame_pkt(
     break;
   default:
     /* We don't support 0-RTT packet in this function. */
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 
   cc.aead = pktns->crypto.ctx.aead;
@@ -4488,7 +4484,17 @@ ngtcp2_ssize ngtcp2_conn_write_single_frame_pkt(
     conn_update_keep_alive_last_ts(conn, ts);
   }
 
-  conn->tx.pacing.pktlen += (size_t)nwrite;
+  if (!padded) {
+    switch (fr->type) {
+    case NGTCP2_FRAME_ACK:
+    case NGTCP2_FRAME_ACK_ECN:
+      break;
+    default:
+      conn->tx.pacing.pktlen += (size_t)nwrite;
+    }
+  } else {
+    conn->tx.pacing.pktlen += (size_t)nwrite;
+  }
 
   ngtcp2_qlog_metrics_updated(&conn->qlog, &conn->cstat);
 
@@ -4689,9 +4695,9 @@ static int conn_start_pmtud(ngtcp2_conn *conn) {
   assert(conn->remote.transport_params->max_udp_payload_size >=
          NGTCP2_MAX_UDP_PAYLOAD_SIZE);
 
-  hard_max_udp_payload_size =
-      (size_t)ngtcp2_min(conn->remote.transport_params->max_udp_payload_size,
-                         (uint64_t)conn->local.settings.max_udp_payload_size);
+  hard_max_udp_payload_size = (size_t)ngtcp2_min(
+      conn->remote.transport_params->max_udp_payload_size,
+      (uint64_t)conn->local.settings.max_tx_udp_payload_size);
 
   rv = ngtcp2_pmtud_new(&conn->pmtud, conn->dcid.current.max_udp_payload_size,
                         hard_max_udp_payload_size,
@@ -4850,9 +4856,9 @@ static size_t conn_shape_udp_payload(ngtcp2_conn *conn, const ngtcp2_dcid *dcid,
   }
 
   payloadlen =
-      ngtcp2_min(payloadlen, conn->local.settings.max_udp_payload_size);
+      ngtcp2_min(payloadlen, conn->local.settings.max_tx_udp_payload_size);
 
-  if (conn->local.settings.no_udp_payload_size_shaping) {
+  if (conn->local.settings.no_tx_udp_payload_size_shaping) {
     return payloadlen;
   }
 
@@ -5999,8 +6005,7 @@ static size_t pkt_num_bits(size_t pkt_numlen) {
   case 4:
     return 32;
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 }
 
@@ -6568,7 +6573,7 @@ conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
     }
     break;
   default:
-    assert(0);
+    ngtcp2_unreachable();
   }
 
   if (payloadlen == 0) {
@@ -9020,7 +9025,7 @@ static ngtcp2_ssize conn_recv_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
       break;
     default:
       /* Unreachable */
-      assert(0);
+      ngtcp2_unreachable();
     }
   } else {
     rv = conn_verify_dcid(conn, &new_cid_used, &hd);
@@ -9899,8 +9904,7 @@ int ngtcp2_conn_read_pkt_versioned(ngtcp2_conn *conn, const ngtcp2_path *path,
     }
     break;
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 
   return conn_recv_cpkt(conn, path, pi, pkt, pktlen, ts);
@@ -11082,15 +11086,28 @@ conn_client_validate_transport_params(ngtcp2_conn *conn,
     assert(vneg_other_versions_includes(conn->vneg.other_versions,
                                         conn->vneg.other_versionslen,
                                         conn->negotiated_version));
-  } else if (conn->client_chosen_version != conn->negotiated_version ||
-             conn->client_chosen_version !=
-                 conn->local.settings.original_version) {
+  } else if (conn->client_chosen_version != conn->negotiated_version) {
     return NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE;
   }
 
   /* When client reacted upon Version Negotiation */
   if (conn->local.settings.original_version != conn->client_chosen_version) {
-    assert(params->version_info_present);
+    if (!params->version_info_present) {
+      assert(conn->client_chosen_version == conn->negotiated_version);
+
+      /* QUIC v1 (and the supported draft versions) are treated
+         specially.  If version_info is missing, no further validation
+         is necessary.
+         https://datatracker.ietf.org/doc/html/draft-ietf-quic-version-negotiation-10#section-8
+       */
+      if (conn->client_chosen_version == NGTCP2_PROTO_VER_V1 ||
+          (NGTCP2_PROTO_VER_DRAFT_MIN <= conn->client_chosen_version &&
+           conn->client_chosen_version <= NGTCP2_PROTO_VER_DRAFT_MAX)) {
+        return 0;
+      }
+
+      return NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE;
+    }
 
     /* Server choose original version after Version Negotiation.
        Draft does not say this particular case, but this smells like
@@ -11499,8 +11516,9 @@ static ngtcp2_ssize conn_write_vmsg_wrapper(ngtcp2_conn *conn,
 
   if (vmsg == NULL && cstat->bytes_in_flight < cstat->cwnd &&
       conn->tx.strmq_nretrans == 0) {
-    if (conn->local.settings.no_udp_payload_size_shaping) {
-      undersized = (size_t)nwrite < conn->local.settings.max_udp_payload_size;
+    if (conn->local.settings.no_tx_udp_payload_size_shaping) {
+      undersized =
+          (size_t)nwrite < conn->local.settings.max_tx_udp_payload_size;
     } else {
       undersized = (size_t)nwrite < conn->dcid.current.max_udp_payload_size;
     }
@@ -11509,7 +11527,7 @@ static ngtcp2_ssize conn_write_vmsg_wrapper(ngtcp2_conn *conn,
       conn->rst.app_limited = conn->rst.delivered + cstat->bytes_in_flight;
 
       if (conn->rst.app_limited == 0) {
-        conn->rst.app_limited = cstat->max_udp_payload_size;
+        conn->rst.app_limited = cstat->max_tx_udp_payload_size;
       }
     }
   }
@@ -11642,14 +11660,16 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
     pi->ecn = NGTCP2_ECN_NOT_ECT;
   }
 
-  if (!conn_pacing_pkt_tx_allowed(conn, ts)) {
-    return 0;
-  }
-
   switch (conn->state) {
   case NGTCP2_CS_CLIENT_INITIAL:
   case NGTCP2_CS_CLIENT_WAIT_HANDSHAKE:
   case NGTCP2_CS_CLIENT_TLS_HANDSHAKE_FAILED:
+    if (!conn_pacing_pkt_tx_allowed(conn, ts)) {
+      assert(!ppe_pending);
+
+      return conn_write_handshake_ack_pkts(conn, pi, dest, origlen, ts);
+    }
+
     nwrite = conn_client_write_handshake(conn, pi, dest, destlen, vmsg, ts);
     /* We might be unable to write a packet because of depletion of
        congestion window budget, perhaps due to packet loss that
@@ -11680,6 +11700,21 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
   case NGTCP2_CS_SERVER_INITIAL:
   case NGTCP2_CS_SERVER_WAIT_HANDSHAKE:
   case NGTCP2_CS_SERVER_TLS_HANDSHAKE_FAILED:
+    if (!conn_pacing_pkt_tx_allowed(conn, ts)) {
+      assert(!ppe_pending);
+
+      if (!(conn->dcid.current.flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) {
+        server_tx_left = conn_server_tx_left(conn, &conn->dcid.current);
+        if (server_tx_left == 0) {
+          return 0;
+        }
+
+        origlen = (size_t)ngtcp2_min((uint64_t)origlen, server_tx_left);
+      }
+
+      return conn_write_handshake_ack_pkts(conn, pi, dest, origlen, ts);
+    }
+
     if (!ppe_pending) {
       if (!(conn->dcid.current.flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) {
         server_tx_left = conn_server_tx_left(conn, &conn->dcid.current);
@@ -11718,7 +11753,7 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
               NGTCP2_DATAGRAM_OVERHEAD;
           break;
         default:
-          assert(0);
+          ngtcp2_unreachable();
         }
 
         if (conn->in_pktns && write_datalen > 0) {
@@ -11758,6 +11793,22 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
     }
     break;
   case NGTCP2_CS_POST_HANDSHAKE:
+    if (!conn_pacing_pkt_tx_allowed(conn, ts)) {
+      assert(!ppe_pending);
+
+      if (conn->server &&
+          !(conn->dcid.current.flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) {
+        server_tx_left = conn_server_tx_left(conn, &conn->dcid.current);
+        if (server_tx_left == 0) {
+          return 0;
+        }
+
+        origlen = (size_t)ngtcp2_min((uint64_t)origlen, server_tx_left);
+      }
+
+      return conn_write_ack_pkt(conn, pi, dest, origlen, NGTCP2_PKT_1RTT, ts);
+    }
+
     break;
   case NGTCP2_CS_CLOSING:
     return NGTCP2_ERR_CLOSING;
@@ -12536,14 +12587,24 @@ static void conn_discard_early_data_state(ngtcp2_conn *conn) {
   }
 }
 
-void ngtcp2_conn_early_data_rejected(ngtcp2_conn *conn) {
+int ngtcp2_conn_early_data_rejected(ngtcp2_conn *conn) {
   if (conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED) {
-    return;
+    return 0;
   }
 
   conn->flags |= NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED;
 
   conn_discard_early_data_state(conn);
+
+  if (conn->callbacks.early_data_rejected) {
+    return conn->callbacks.early_data_rejected(conn, conn->user_data);
+  }
+
+  return 0;
+}
+
+int ngtcp2_conn_get_early_data_rejected(ngtcp2_conn *conn) {
+  return (conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED) != 0;
 }
 
 int ngtcp2_conn_update_rtt(ngtcp2_conn *conn, ngtcp2_duration rtt,
@@ -12619,7 +12680,7 @@ static void conn_get_loss_time_and_pktns(ngtcp2_conn *conn,
   ngtcp2_pktns *pktns = conn->in_pktns;
   size_t i;
 
-  for (i = 0; i < sizeof(ns) / sizeof(ns[0]); ++i) {
+  for (i = 0; i < ngtcp2_arraylen(ns); ++i) {
     if (ns[i] == NULL || loss_time[i] >= earliest_loss_time) {
       continue;
     }
@@ -13035,13 +13096,13 @@ const ngtcp2_path *ngtcp2_conn_get_path(ngtcp2_conn *conn) {
   return &conn->dcid.current.ps.path;
 }
 
-size_t ngtcp2_conn_get_max_udp_payload_size(ngtcp2_conn *conn) {
-  return conn->local.settings.max_udp_payload_size;
+size_t ngtcp2_conn_get_max_tx_udp_payload_size(ngtcp2_conn *conn) {
+  return conn->local.settings.max_tx_udp_payload_size;
 }
 
-size_t ngtcp2_conn_get_path_max_udp_payload_size(ngtcp2_conn *conn) {
-  if (conn->local.settings.no_udp_payload_size_shaping) {
-    return ngtcp2_conn_get_max_udp_payload_size(conn);
+size_t ngtcp2_conn_get_path_max_tx_udp_payload_size(ngtcp2_conn *conn) {
+  if (conn->local.settings.no_tx_udp_payload_size_shaping) {
+    return ngtcp2_conn_get_max_tx_udp_payload_size(conn);
   }
 
   return conn->dcid.current.max_udp_payload_size;
@@ -13342,23 +13403,25 @@ int ngtcp2_conn_set_stream_user_data(ngtcp2_conn *conn, int64_t stream_id,
 }
 
 void ngtcp2_conn_update_pkt_tx_time(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
+  double pacing_rate;
+  ngtcp2_duration interval;
+
   if (conn->tx.pacing.pktlen == 0) {
     return;
   }
 
   if (conn->cstat.pacing_rate > 0) {
-    conn->tx.pacing.next_ts =
-        ts + (ngtcp2_duration)((double)conn->tx.pacing.pktlen /
-                               conn->cstat.pacing_rate);
+    pacing_rate = conn->cstat.pacing_rate;
   } else {
-    double pacing_rate =
-        (double)conn->cstat.cwnd / (double)(conn->cstat.min_rtt != UINT64_MAX
-                                                ? conn->cstat.min_rtt
-                                                : NGTCP2_MILLISECONDS);
-    conn->tx.pacing.next_ts =
-        ts + (ngtcp2_duration)((double)conn->tx.pacing.pktlen / pacing_rate);
+    /* 1.25 is the under-utilization avoidance factor described in
+       https://datatracker.ietf.org/doc/html/rfc9002#section-7.7 */
+    pacing_rate =
+        (double)conn->cstat.cwnd / (double)conn->cstat.smoothed_rtt * 1.25;
   }
 
+  interval = (ngtcp2_duration)((double)conn->tx.pacing.pktlen / pacing_rate);
+
+  conn->tx.pacing.next_ts = ts + interval;
   conn->tx.pacing.pktlen = 0;
 }
 
@@ -13370,15 +13433,14 @@ int ngtcp2_conn_track_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
   size_t i;
 
   if (conn->dcid.retire_unacked.len >=
-      sizeof(conn->dcid.retire_unacked.seqs) /
-          sizeof(conn->dcid.retire_unacked.seqs[0])) {
+      ngtcp2_arraylen(conn->dcid.retire_unacked.seqs)) {
     return NGTCP2_ERR_CONNECTION_ID_LIMIT;
   }
 
   /* Make sure that we do not have a duplicate */
   for (i = 0; i < conn->dcid.retire_unacked.len; ++i) {
     if (conn->dcid.retire_unacked.seqs[i] == seq) {
-      assert(0);
+      ngtcp2_unreachable();
     }
   }
 
@@ -13431,7 +13493,7 @@ void ngtcp2_settings_default_versioned(int settings_version,
   settings->cc_algo = NGTCP2_CC_ALGO_CUBIC;
   settings->initial_rtt = NGTCP2_DEFAULT_INITIAL_RTT;
   settings->ack_thresh = 2;
-  settings->max_udp_payload_size = 1500 - 48;
+  settings->max_tx_udp_payload_size = 1500 - 48;
   settings->handshake_timeout = NGTCP2_DEFAULT_HANDSHAKE_TIMEOUT;
 }
 
index dcf72e4d0ec98084707ffe0565ef34a7f4a4e970..d2c19f3a7b9683b02b76e397d55d92686b7a314a 100644 (file)
@@ -30,6 +30,7 @@
 #include "ngtcp2_str.h"
 #include "ngtcp2_pkt.h"
 #include "ngtcp2_net.h"
+#include "ngtcp2_unreachable.h"
 
 uint64_t ngtcp2_get_uint64(const uint8_t *p) {
   uint64_t n;
@@ -87,7 +88,7 @@ uint64_t ngtcp2_get_varint(size_t *plen, const uint8_t *p) {
     n.b[0] &= 0x3f;
     return ngtcp2_ntohl64(n.n64);
   default:
-    assert(0);
+    ngtcp2_unreachable();
   }
 
   return 0;
@@ -104,8 +105,7 @@ int64_t ngtcp2_get_pkt_num(const uint8_t *p, size_t pkt_numlen) {
   case 4:
     return (int64_t)ngtcp2_get_uint32(p);
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 }
 
@@ -182,8 +182,7 @@ uint8_t *ngtcp2_put_pkt_num(uint8_t *p, int64_t pkt_num, size_t len) {
     ngtcp2_put_uint32be(p, (uint32_t)pkt_num);
     return p + 4;
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 }
 
index ee37ff3517b2bc9603f6b1e964527e0fbd7d2cdb..de532238ee85ede6b446d119b7b8748bf5b8aba5 100644 (file)
@@ -35,6 +35,7 @@
 #include "ngtcp2_vec.h"
 #include "ngtcp2_macro.h"
 #include "ngtcp2_conv.h"
+#include "ngtcp2_unreachable.h"
 
 void ngtcp2_log_init(ngtcp2_log *log, const ngtcp2_cid *scid,
                      ngtcp2_printf log_printf, ngtcp2_tstamp ts,
@@ -535,7 +536,7 @@ static void log_fr(ngtcp2_log *log, const ngtcp2_pkt_hd *hd,
     log_fr_datagram(log, hd, &fr->datagram, dir);
     break;
   default:
-    assert(0);
+    ngtcp2_unreachable();
   }
 }
 
index e2603aae15dd040a030a6781e1a2f5123e7a8fb6..28d3461bef9238d179f98f9ae1df63508a518cf7 100644 (file)
@@ -50,4 +50,9 @@
     *(PD) = (T);                                                               \
   } while (0)
 
+/*
+ * ngtcp2_arraylen returns the number of elements in array |A|.
+ */
+#define ngtcp2_arraylen(A) (sizeof(A) / sizeof(A[0]))
+
 #endif /* NGTCP2_MACRO_H */
index 7a99ab3414997188f63af1f4b21c34cfd73944df..abc340b4f41da454711c8a8b6ff40442df501844 100644 (file)
@@ -33,6 +33,7 @@
 #include "ngtcp2_cid.h"
 #include "ngtcp2_mem.h"
 #include "ngtcp2_vec.h"
+#include "ngtcp2_unreachable.h"
 
 int ngtcp2_pkt_chain_new(ngtcp2_pkt_chain **ppc, const ngtcp2_path *path,
                          const ngtcp2_pkt_info *pi, const uint8_t *pkt,
@@ -218,7 +219,7 @@ ngtcp2_ssize ngtcp2_pkt_decode_hd_long(ngtcp2_pkt_hd *dest, const uint8_t *pkt,
       break;
     default:
       /* Unreachable */
-      assert(0);
+      ngtcp2_unreachable();
     }
   }
 
@@ -1472,8 +1473,7 @@ ngtcp2_ssize ngtcp2_pkt_decode_datagram_frame(ngtcp2_datagram *dest,
     len += datalen;
     break;
   default:
-    assert(0);
-    abort();
+    ngtcp2_unreachable();
   }
 
   dest->type = type;
@@ -2538,8 +2538,7 @@ uint8_t ngtcp2_pkt_versioned_type(uint32_t version, uint32_t pkt_type) {
     case NGTCP2_PKT_RETRY:
       return NGTCP2_PKT_TYPE_RETRY_V2_DRAFT;
     default:
-      assert(0);
-      abort();
+      ngtcp2_unreachable();
     }
   default:
     /* Assume that unsupported versions share the numeric long packet
@@ -2558,8 +2557,7 @@ uint8_t ngtcp2_pkt_versioned_type(uint32_t version, uint32_t pkt_type) {
     case NGTCP2_PKT_RETRY:
       return NGTCP2_PKT_TYPE_RETRY_V1;
     default:
-      assert(0);
-      abort();
+      ngtcp2_unreachable();
     }
   }
 }
index 26318bb1c8e38cc52c7985a7ce624389e22020b7..771ef5e026d12df79d5a9b10140bd5463afe3b43 100644 (file)
@@ -41,7 +41,7 @@ static size_t mtu_probes[] = {
     1492 - 48, /* PPPoE */
 };
 
-static size_t mtu_probeslen = sizeof(mtu_probes) / sizeof(mtu_probes[0]);
+#define NGTCP2_MTU_PROBESLEN ngtcp2_arraylen(mtu_probes)
 
 int ngtcp2_pmtud_new(ngtcp2_pmtud **ppmtud, size_t max_udp_payload_size,
                      size_t hard_max_udp_payload_size, int64_t tx_pkt_num,
@@ -61,7 +61,7 @@ int ngtcp2_pmtud_new(ngtcp2_pmtud **ppmtud, size_t max_udp_payload_size,
   pmtud->hard_max_udp_payload_size = hard_max_udp_payload_size;
   pmtud->min_fail_udp_payload_size = SIZE_MAX;
 
-  for (; pmtud->mtu_idx < mtu_probeslen; ++pmtud->mtu_idx) {
+  for (; pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN; ++pmtud->mtu_idx) {
     if (mtu_probes[pmtud->mtu_idx] > pmtud->hard_max_udp_payload_size) {
       continue;
     }
@@ -84,7 +84,7 @@ void ngtcp2_pmtud_del(ngtcp2_pmtud *pmtud) {
 }
 
 size_t ngtcp2_pmtud_probelen(ngtcp2_pmtud *pmtud) {
-  assert(pmtud->mtu_idx < mtu_probeslen);
+  assert(pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN);
 
   return mtu_probes[pmtud->mtu_idx];
 }
@@ -107,13 +107,13 @@ int ngtcp2_pmtud_require_probe(ngtcp2_pmtud *pmtud) {
 }
 
 static void pmtud_next_probe(ngtcp2_pmtud *pmtud) {
-  assert(pmtud->mtu_idx < mtu_probeslen);
+  assert(pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN);
 
   ++pmtud->mtu_idx;
   pmtud->num_pkts_sent = 0;
   pmtud->expiry = UINT64_MAX;
 
-  for (; pmtud->mtu_idx < mtu_probeslen; ++pmtud->mtu_idx) {
+  for (; pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN; ++pmtud->mtu_idx) {
     if (mtu_probes[pmtud->mtu_idx] <= pmtud->max_udp_payload_size ||
         mtu_probes[pmtud->mtu_idx] > pmtud->hard_max_udp_payload_size) {
       continue;
@@ -129,7 +129,7 @@ void ngtcp2_pmtud_probe_success(ngtcp2_pmtud *pmtud, size_t payloadlen) {
   pmtud->max_udp_payload_size =
       ngtcp2_max(pmtud->max_udp_payload_size, payloadlen);
 
-  assert(pmtud->mtu_idx < mtu_probeslen);
+  assert(pmtud->mtu_idx < NGTCP2_MTU_PROBESLEN);
 
   if (mtu_probes[pmtud->mtu_idx] > pmtud->max_udp_payload_size) {
     return;
@@ -156,5 +156,5 @@ void ngtcp2_pmtud_handle_expiry(ngtcp2_pmtud *pmtud, ngtcp2_tstamp ts) {
 }
 
 int ngtcp2_pmtud_finished(ngtcp2_pmtud *pmtud) {
-  return pmtud->mtu_idx >= mtu_probeslen;
+  return pmtud->mtu_idx >= NGTCP2_MTU_PROBESLEN;
 }
index 69eaeb7367438d0e7644700985638b7add2f93b2..b6618efbe41b0e11834c8122438d006e26c35f62 100644 (file)
@@ -30,6 +30,7 @@
 #include "ngtcp2_vec.h"
 #include "ngtcp2_conv.h"
 #include "ngtcp2_net.h"
+#include "ngtcp2_unreachable.h"
 
 void ngtcp2_qlog_init(ngtcp2_qlog *qlog, ngtcp2_qlog_write write,
                       ngtcp2_tstamp ts, void *user_data) {
@@ -897,7 +898,7 @@ void ngtcp2_qlog_write_frame(ngtcp2_qlog *qlog, const ngtcp2_frame *fr) {
     p = write_datagram_frame(p, &fr->datagram);
     break;
   default:
-    assert(0);
+    ngtcp2_unreachable();
   }
 
   *p++ = ',';
index 644071400a6eb7d0e212ef1b8a151086b98fd13c..1ccd567a3c822e02025242297942f193eb064364 100644 (file)
@@ -34,6 +34,7 @@
 #include "ngtcp2_cc.h"
 #include "ngtcp2_rcvry.h"
 #include "ngtcp2_rst.h"
+#include "ngtcp2_unreachable.h"
 
 int ngtcp2_frame_chain_new(ngtcp2_frame_chain **pfrc, const ngtcp2_mem *mem) {
   *pfrc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_frame_chain));
@@ -840,7 +841,7 @@ static int rtb_process_acked_pkt(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent,
         pktns = &conn->pktns;
         break;
       default:
-        assert(0);
+        ngtcp2_unreachable();
       }
 
       conn_ack_crypto_data(conn, pktns, datalen);
@@ -1189,7 +1190,7 @@ static int rtb_detect_lost_pkt(ngtcp2_rtb *rtb, uint64_t *ppkt_lost,
   ngtcp2_cc *cc = rtb->cc;
   int rv;
   uint64_t pkt_thres =
-      rtb->cc_bytes_in_flight / cstat->max_udp_payload_size / 2;
+      rtb->cc_bytes_in_flight / cstat->max_tx_udp_payload_size / 2;
   size_t ecn_pkt_lost = 0;
   ngtcp2_tstamp start_ts;
   ngtcp2_duration pto = ngtcp2_conn_compute_pto(conn, pktns);
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.c
new file mode 100644 (file)
index 0000000..7c7d9ae
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * ngtcp2
+ *
+ * Copyright (c) 2022 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_unreachable.h"
+
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <stdlib.h>
+#ifdef WIN32
+#  include <io.h>
+#endif /* WIN32 */
+
+void ngtcp2_unreachable_fail(const char *file, int line, const char *func) {
+  char *buf;
+  size_t buflen;
+  int rv;
+
+#define NGTCP2_UNREACHABLE_TEMPLATE "%s:%d %s: Unreachable.\n"
+
+  rv = snprintf(NULL, 0, NGTCP2_UNREACHABLE_TEMPLATE, file, line, func);
+  if (rv < 0) {
+    abort();
+  }
+
+  /* here we explicitly use system malloc */
+  buflen = (size_t)rv + 1;
+  buf = malloc(buflen);
+  if (buf == NULL) {
+    abort();
+  }
+
+  rv = snprintf(buf, buflen, NGTCP2_UNREACHABLE_TEMPLATE, file, line, func);
+  if (rv < 0) {
+    abort();
+  }
+
+#ifndef WIN32
+  while (write(STDERR_FILENO, buf, (size_t)rv) == -1 && errno == EINTR)
+    ;
+#else  /* WIN32 */
+  _write(_fileno(stderr), buf, (unsigned int)rv);
+#endif /* WIN32 */
+
+  free(buf);
+
+  abort();
+}
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.h b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_unreachable.h
new file mode 100644 (file)
index 0000000..11a6aaa
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * ngtcp2
+ *
+ * Copyright (c) 2022 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_UNREACHABLE_H
+#define NGTCP2_UNREACHABLE_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <ngtcp2/ngtcp2.h>
+
+#define ngtcp2_unreachable()                                                   \
+  ngtcp2_unreachable_fail(__FILE__, __LINE__, __func__)
+
+#ifdef _MSC_VER
+__declspec(noreturn)
+#endif /* _MSC_VER */
+    void ngtcp2_unreachable_fail(const char *file, int line, const char *func)
+#ifndef _MSC_VER
+        __attribute__((noreturn))
+#endif /* !_MSC_VER */
+        ;
+
+#endif /* NGTCP2_UNREACHABLE_H */
index ed1182d0514e9a21f49282ede6c1136ebc979e2d..06322492830862c74bf7c10227f241a704b77397 100644 (file)
@@ -1507,10 +1507,9 @@ typedef struct ngtcp2_transport_params {
   uint8_t stateless_reset_token[NGTCP2_STATELESS_RESET_TOKENLEN];
   /**
    * :member:`grease_quic_bit` is nonzero if sender supports "Greasing
-   * the QUIC Bit" extension.  See
-   * https://datatracker.ietf.org/doc/html/draft-ietf-quic-bit-grease.
-   * Note that the local endpoint always enables greasing QUIC bit
-   * regardless of this field value.
+   * the QUIC Bit" extension.  See :rfc:`9287`.  Note that the local
+   * endpoint always enables greasing QUIC bit regardless of this
+   * field value.
    */
   uint8_t grease_quic_bit;
   /**
@@ -1631,11 +1630,11 @@ typedef struct ngtcp2_conn_stat {
    */
   uint64_t bytes_in_flight;
   /**
-   * :member:`max_udp_payload_size` is the maximum size of UDP
+   * :member:`max_tx_udp_payload_size` is the maximum size of UDP
    * datagram payload that this endpoint transmits.  It is used by
    * congestion controller to compute congestion window.
    */
-  size_t max_udp_payload_size;
+  size_t max_tx_udp_payload_size;
   /**
    * :member:`delivery_rate_sec` is the current sending rate measured
    * in byte per second.
@@ -1789,11 +1788,11 @@ typedef struct ngtcp2_settings {
    */
   ngtcp2_printf log_printf;
   /**
-   * :member:`max_udp_payload_size` is the maximum size of UDP
+   * :member:`max_tx_udp_payload_size` is the maximum size of UDP
    * datagram payload that this endpoint transmits.  It is used by
    * congestion controller to compute congestion window.
    */
-  size_t max_udp_payload_size;
+  size_t max_tx_udp_payload_size;
   /**
    * :member:`token` is a token from Retry packet or NEW_TOKEN frame.
    *
@@ -1840,14 +1839,14 @@ typedef struct ngtcp2_settings {
    */
   size_t ack_thresh;
   /**
-   * :member:`no_udp_payload_size_shaping`, if set to nonzero,
+   * :member:`no_tx_udp_payload_size_shaping`, if set to nonzero,
    * instructs the library not to limit the UDP payload size to
    * :macro:`NGTCP2_MAX_UDP_PAYLOAD_SIZE` (which can be extended by
    * Path MTU Discovery) and instead use the mininum size among the
-   * given buffer size, :member:`max_udp_payload_size`, and the
+   * given buffer size, :member:`max_tx_udp_payload_size`, and the
    * received max_udp_payload QUIC transport parameter.
    */
-  int no_udp_payload_size_shaping;
+  int no_tx_udp_payload_size_shaping;
   /**
    * :member:`handshake_timeout` is the period of time before giving
    * up QUIC connection establishment.  If QUIC handshake is not
@@ -3320,6 +3319,18 @@ typedef int (*ngtcp2_version_negotiation)(ngtcp2_conn *conn, uint32_t version,
 typedef int (*ngtcp2_recv_key)(ngtcp2_conn *conn, ngtcp2_crypto_level level,
                                void *user_data);
 
+/**
+ * @functypedef
+ *
+ * :type:`ngtcp2_early_data_rejected` is invoked when early data was
+ * rejected by server, or client decided not to attempt early data.
+ *
+ * The callback function must return 0 if it succeeds.  Returning
+ * :macro:`NGTCP2_ERR_CALLBACK_FAILURE` makes the library call return
+ * immediately.
+ */
+typedef int (*ngtcp2_early_data_rejected)(ngtcp2_conn *conn, void *user_data);
+
 #define NGTCP2_CALLBACKS_VERSION_V1 1
 #define NGTCP2_CALLBACKS_VERSION NGTCP2_CALLBACKS_VERSION_V1
 
@@ -3578,6 +3589,13 @@ typedef struct ngtcp2_callbacks {
    * :enum:`ngtcp2_crypto_level.NGTCP2_CRYPTO_LEVEL_INITIAL`.
    */
   ngtcp2_recv_key recv_tx_key;
+  /**
+   * :member:`ngtcp2_early_data_rejected` is a callback function which
+   * is invoked when an attempt to send early data by client was
+   * rejected by server, or client decided not to attempt early data.
+   * This callback function is only used by client.
+   */
+  ngtcp2_early_data_rejected early_data_rejected;
 } ngtcp2_callbacks;
 
 /**
@@ -4397,7 +4415,7 @@ NGTCP2_EXTERN ngtcp2_ssize ngtcp2_conn_write_stream_versioned(
  * handshake as well.
  *
  * |destlen| should be at least
- * :member:`ngtcp2_settings.max_udp_payload_size`.
+ * :member:`ngtcp2_settings.max_tx_udp_payload_size`.
  *
  * Specifying -1 to |stream_id| means no new stream data to send.
  *
@@ -4550,7 +4568,7 @@ NGTCP2_EXTERN ngtcp2_ssize ngtcp2_conn_writev_stream_versioned(
  * as well.
  *
  * |destlen| should be at least
- * :member:`ngtcp2_settings.max_udp_payload_size`.
+ * :member:`ngtcp2_settings.max_tx_udp_payload_size`.
  *
  * For |path| and |pi| parameters, refer to
  * `ngtcp2_conn_writev_stream`.
@@ -4817,8 +4835,8 @@ NGTCP2_EXTERN uint32_t ngtcp2_conn_get_negotiated_version(ngtcp2_conn *conn);
  * @function
  *
  * `ngtcp2_conn_early_data_rejected` tells |conn| that early data was
- * rejected by a server.  |conn| discards the following connection
- * states:
+ * rejected by a server, or client decided not to attempt early data
+ * for some reason.  |conn| discards the following connection states:
  *
  * - Any opended streams.
  * - Stream identifier allocations.
@@ -4828,8 +4846,22 @@ NGTCP2_EXTERN uint32_t ngtcp2_conn_get_negotiated_version(ngtcp2_conn *conn);
  *
  * Application which wishes to retransmit early data, it has to open
  * streams and send stream data again.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :macro:`NGTCP2_ERR_CALLBACK_FAILURE`
+ *     User callback failed
  */
-NGTCP2_EXTERN void ngtcp2_conn_early_data_rejected(ngtcp2_conn *conn);
+NGTCP2_EXTERN int ngtcp2_conn_early_data_rejected(ngtcp2_conn *conn);
+
+/**
+ * @function
+ *
+ * `ngtcp2_conn_get_early_data_rejected` returns nonzero if
+ * `ngtcp2_conn_early_data_rejected` has been called.
+ */
+NGTCP2_EXTERN int ngtcp2_conn_get_early_data_rejected(ngtcp2_conn *conn);
 
 /**
  * @function
@@ -4904,25 +4936,25 @@ NGTCP2_EXTERN const ngtcp2_path *ngtcp2_conn_get_path(ngtcp2_conn *conn);
 /**
  * @function
  *
- * `ngtcp2_conn_get_max_udp_payload_size` returns the maximum UDP
+ * `ngtcp2_conn_get_max_tx_udp_payload_size` returns the maximum UDP
  * payload size that this local endpoint would send.  This is the
- * value of :member:`ngtcp2_settings.max_udp_payload_size` that is
+ * value of :member:`ngtcp2_settings.max_tx_udp_payload_size` that is
  * passed to `ngtcp2_conn_client_new` or `ngtcp2_conn_server_new`.
  */
-NGTCP2_EXTERN size_t ngtcp2_conn_get_max_udp_payload_size(ngtcp2_conn *conn);
+NGTCP2_EXTERN size_t ngtcp2_conn_get_max_tx_udp_payload_size(ngtcp2_conn *conn);
 
 /**
  * @function
  *
- * `ngtcp2_conn_get_path_max_udp_payload_size` returns the maximum UDP
- * payload size for the current path.  If
- * :member:`ngtcp2_settings.no_udp_payload_size_shaping` is set to
+ * `ngtcp2_conn_get_path_max_tx_udp_payload_size` returns the maximum
+ * UDP payload size for the current path.  If
+ * :member:`ngtcp2_settings.no_tx_udp_payload_size_shaping` is set to
  * nonzero, this function is equivalent to
- * `ngtcp2_conn_get_max_udp_payload_size`.  Otherwise, it returns the
- * maximum UDP payload size that is probed for the current path.
+ * `ngtcp2_conn_get_max_tx_udp_payload_size`.  Otherwise, it returns
+ * the maximum UDP payload size that is probed for the current path.
  */
 NGTCP2_EXTERN size_t
-ngtcp2_conn_get_path_max_udp_payload_size(ngtcp2_conn *conn);
+ngtcp2_conn_get_path_max_tx_udp_payload_size(ngtcp2_conn *conn);
 
 /**
  * @function
@@ -5513,8 +5545,8 @@ NGTCP2_EXTERN void ngtcp2_path_storage_zero(ngtcp2_path_storage *ps);
  * * :type:`initial_rtt <ngtcp2_settings.initial_rtt>` =
  *   :macro:`NGTCP2_DEFAULT_INITIAL_RTT`
  * * :type:`ack_thresh <ngtcp2_settings.ack_thresh>` = 2
- * * :type:`max_udp_payload_size
- *   <ngtcp2_settings.max_udp_payload_size>` = 1452
+ * * :type:`max_tx_udp_payload_size
+ *   <ngtcp2_settings.max_tx_udp_payload_size>` = 1452
  * * :type:`handshake_timeout <ngtcp2_settings.handshake_timeout>` =
  *   :macro:`NGTCP2_DEFAULT_HANDSHAKE_TIMEOUT`.
  */
index 07e46d2eefa5ea260da8ce6505dd0b11191a7b86..6a2544ccc498204b1e71a4f24e73f506f4ef4fc6 100644 (file)
@@ -36,7 +36,7 @@
  *
  * Version number of the ngtcp2 library release.
  */
-#define NGTCP2_VERSION "0.9.0"
+#define NGTCP2_VERSION "0.10.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 0x000900
+#define NGTCP2_VERSION_NUM 0x000a00
 
 #endif /* VERSION_H */