summaryrefslogtreecommitdiffstats
path: root/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c591
1 files changed, 280 insertions, 311 deletions
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
index c8caf47..a8e8874 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_conn.c
@@ -37,7 +37,8 @@
#include "ngtcp2_rcvry.h"
#include "ngtcp2_unreachable.h"
#include "ngtcp2_net.h"
-#include "ngtcp2_conversion.h"
+#include "ngtcp2_transport_params.h"
+#include "ngtcp2_settings.h"
#include "ngtcp2_tstamp.h"
#include "ngtcp2_frame_chain.h"
@@ -663,13 +664,11 @@ static int conn_call_recv_tx_key(ngtcp2_conn *conn,
return 0;
}
-static int pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
- ngtcp2_rst *rst, ngtcp2_cc *cc, int64_t initial_pkt_num,
- ngtcp2_log *log, ngtcp2_qlog *qlog,
- ngtcp2_objalloc *rtb_entry_objalloc,
- ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
- int rv;
-
+static void pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
+ ngtcp2_rst *rst, ngtcp2_cc *cc, int64_t initial_pkt_num,
+ ngtcp2_log *log, ngtcp2_qlog *qlog,
+ ngtcp2_objalloc *rtb_entry_objalloc,
+ ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
memset(pktns, 0, sizeof(*pktns));
ngtcp2_gaptr_init(&pktns->rx.pngap, mem);
@@ -679,10 +678,7 @@ static int pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
pktns->rx.max_pkt_num = -1;
pktns->rx.max_ack_eliciting_pkt_num = -1;
- rv = ngtcp2_acktr_init(&pktns->acktr, log, mem);
- if (rv != 0) {
- goto fail_acktr_init;
- }
+ ngtcp2_acktr_init(&pktns->acktr, log, mem);
ngtcp2_strm_init(&pktns->crypto.strm, 0, NGTCP2_STRM_FLAG_NONE, 0, 0, NULL,
frc_objalloc, mem);
@@ -690,13 +686,6 @@ static int pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
ngtcp2_rtb_init(&pktns->rtb, pktns_id, &pktns->crypto.strm, rst, cc,
initial_pkt_num, log, qlog, rtb_entry_objalloc, frc_objalloc,
mem);
-
- return 0;
-
-fail_acktr_init:
- ngtcp2_gaptr_free(&pktns->rx.pngap);
-
- return rv;
}
static int pktns_new(ngtcp2_pktns **ppktns, ngtcp2_pktns_id pktns_id,
@@ -704,20 +693,15 @@ static int pktns_new(ngtcp2_pktns **ppktns, ngtcp2_pktns_id pktns_id,
ngtcp2_log *log, ngtcp2_qlog *qlog,
ngtcp2_objalloc *rtb_entry_objalloc,
ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
- int rv;
-
*ppktns = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_pktns));
if (*ppktns == NULL) {
return NGTCP2_ERR_NOMEM;
}
- rv = pktns_init(*ppktns, pktns_id, rst, cc, initial_pkt_num, log, qlog,
- rtb_entry_objalloc, frc_objalloc, mem);
- if (rv != 0) {
- ngtcp2_mem_free(mem, *ppktns);
- }
+ pktns_init(*ppktns, pktns_id, rst, cc, initial_pkt_num, log, qlog,
+ rtb_entry_objalloc, frc_objalloc, mem);
- return rv;
+ return 0;
}
static int cycle_less(const ngtcp2_pq_entry *lhs, const ngtcp2_pq_entry *rhs) {
@@ -803,8 +787,9 @@ static void conn_reset_conn_stat_cc(ngtcp2_conn *conn,
cstat->first_rtt_sample_ts = UINT64_MAX;
cstat->pto_count = 0;
cstat->loss_detection_timer = UINT64_MAX;
- cstat->cwnd =
- ngtcp2_cc_compute_initcwnd(conn->local.settings.max_tx_udp_payload_size);
+ cstat->max_tx_udp_payload_size =
+ ngtcp2_conn_get_path_max_tx_udp_payload_size(conn);
+ cstat->cwnd = ngtcp2_cc_compute_initcwnd(cstat->max_tx_udp_payload_size);
cstat->ssthresh = UINT64_MAX;
cstat->congestion_recovery_start_ts = UINT64_MAX;
cstat->bytes_in_flight = 0;
@@ -847,7 +832,7 @@ static void delete_scid(ngtcp2_ksl *scids, const ngtcp2_mem *mem) {
static ngtcp2_duration compute_pto(ngtcp2_duration smoothed_rtt,
ngtcp2_duration rttvar,
ngtcp2_duration max_ack_delay) {
- ngtcp2_duration var = ngtcp2_max(4 * rttvar, NGTCP2_GRANULARITY);
+ ngtcp2_duration var = ngtcp2_max_uint64(4 * rttvar, NGTCP2_GRANULARITY);
return smoothed_rtt + var + max_ack_delay;
}
@@ -1007,28 +992,15 @@ static void conn_reset_ecn_validation_state(ngtcp2_conn *conn) {
static uint8_t server_default_available_versions[] = {0, 0, 0, 1};
/*
- * available_versions_new allocates new buffer, and writes |versions|
- * of length |versionslen| in network byte order, suitable for sending
- * in available_versions field of version_information QUIC transport
- * parameter. The pointer to the allocated buffer is assigned to
- * |*pbuf|.
- *
- * This function returns 0 if it succeeds, or one of the negative
- * error codes:
- *
- * NGTCP2_ERR_NOMEM
- * Out of memory.
+ * available_versions_init writes |versions| of length |versionslen|
+ * in network byte order to the buffer pointed by |buf|, suitable for
+ * sending in available_versions field of version_information QUIC
+ * transport parameter. This function returns the pointer to the one
+ * beyond the last byte written.
*/
-static int available_versions_new(uint8_t **pbuf, const uint32_t *versions,
- size_t versionslen, const ngtcp2_mem *mem) {
+static void *available_versions_init(void *buf, const uint32_t *versions,
+ size_t versionslen) {
size_t i;
- uint8_t *buf = ngtcp2_mem_malloc(mem, sizeof(uint32_t) * versionslen);
-
- if (buf == NULL) {
- return NGTCP2_ERR_NOMEM;
- }
-
- *pbuf = buf;
for (i = 0; i < versionslen; ++i) {
buf = ngtcp2_put_uint32be(buf, versions[i]);
@@ -1055,6 +1027,16 @@ conn_set_local_transport_params(ngtcp2_conn *conn,
p->version_info_present = 1;
}
+static size_t buflen_align(size_t buflen) {
+ return (buflen + 0x7) & (size_t)~0x7;
+}
+
+static void *buf_align(void *buf) {
+ return (void *)((uintptr_t)((uint8_t *)buf + 0x7) & (uintptr_t)~0x7);
+}
+
+static void *buf_advance(void *buf, size_t n) { return (uint8_t *)buf + n; }
+
static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
const ngtcp2_cid *scid, const ngtcp2_path *path,
uint32_t client_chosen_version, int callbacks_version,
@@ -1065,14 +1047,18 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
const ngtcp2_mem *mem, void *user_data, int server) {
int rv;
ngtcp2_scid *scident;
- uint8_t *buf;
+ void *buf, *tokenbuf;
+ size_t buflen;
uint8_t fixed_bit_byte;
size_t i;
uint32_t *preferred_versions;
+ ngtcp2_settings settingsbuf;
ngtcp2_transport_params paramsbuf;
(void)callbacks_version;
(void)settings_version;
+ settings = ngtcp2_settings_convert_to_latest(&settingsbuf, settings_version,
+ settings);
params = ngtcp2_transport_params_convert_to_latest(
&paramsbuf, transport_params_version, params);
@@ -1111,16 +1097,54 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
assert(callbacks->get_path_challenge_data);
assert(!server || !ngtcp2_is_reserved_version(client_chosen_version));
+ for (i = 0; i < settings->pmtud_probeslen; ++i) {
+ assert(settings->pmtud_probes[i] > NGTCP2_MAX_UDP_PAYLOAD_SIZE);
+ }
+
if (mem == NULL) {
mem = ngtcp2_mem_default();
}
- *pconn = ngtcp2_mem_calloc(mem, 1, sizeof(ngtcp2_conn));
- if (*pconn == NULL) {
- rv = NGTCP2_ERR_NOMEM;
- goto fail_conn;
+ buflen = sizeof(ngtcp2_conn);
+ if (settings->qlog_write) {
+ buflen = buflen_align(buflen);
+ buflen += NGTCP2_QLOG_BUFLEN;
+ }
+
+ if (settings->pmtud_probeslen) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(settings->pmtud_probes[0]) * settings->pmtud_probeslen;
+ }
+
+ if (settings->preferred_versionslen) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(settings->preferred_versions[0]) *
+ settings->preferred_versionslen;
+ }
+
+ if (settings->available_versionslen) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(settings->available_versions[0]) *
+ settings->available_versionslen;
+ } else if (server) {
+ if (settings->preferred_versionslen) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(settings->preferred_versions[0]) *
+ settings->preferred_versionslen;
+ }
+ } else if (!ngtcp2_is_reserved_version(client_chosen_version)) {
+ buflen = buflen_align(buflen);
+ buflen += sizeof(client_chosen_version);
}
+ buf = ngtcp2_mem_calloc(mem, 1, buflen);
+ if (buf == NULL) {
+ return NGTCP2_ERR_NOMEM;
+ }
+
+ *pconn = buf;
+ buf = buf_advance(buf, sizeof(ngtcp2_conn));
+
(*pconn)->server = server;
ngtcp2_objalloc_frame_chain_init(&(*pconn)->frc_objalloc, 64, mem);
@@ -1154,36 +1178,47 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
ngtcp2_qlog_init(&(*pconn)->qlog, settings->qlog_write, settings->initial_ts,
user_data);
if ((*pconn)->qlog.write) {
- buf = ngtcp2_mem_malloc(mem, NGTCP2_QLOG_BUFLEN);
- if (buf == NULL) {
- rv = NGTCP2_ERR_NOMEM;
- goto fail_qlog_buf;
- }
+ buf = buf_align(buf);
ngtcp2_buf_init(&(*pconn)->qlog.buf, buf, NGTCP2_QLOG_BUFLEN);
+ buf = buf_advance(buf, NGTCP2_QLOG_BUFLEN);
}
(*pconn)->local.settings = *settings;
if (settings->tokenlen) {
- buf = ngtcp2_mem_malloc(mem, settings->tokenlen);
- if (buf == NULL) {
+ tokenbuf = ngtcp2_mem_malloc(mem, settings->tokenlen);
+ if (tokenbuf == NULL) {
rv = NGTCP2_ERR_NOMEM;
goto fail_token;
}
- memcpy(buf, settings->token, settings->tokenlen);
- (*pconn)->local.settings.token = buf;
+ memcpy(tokenbuf, settings->token, settings->tokenlen);
+ (*pconn)->local.settings.token = tokenbuf;
} else {
(*pconn)->local.settings.token = NULL;
}
+ if (settings->pmtud_probeslen) {
+ (*pconn)->local.settings.pmtud_probes = buf_align(buf);
+ buf = ngtcp2_cpymem((uint16_t *)(*pconn)->local.settings.pmtud_probes,
+ settings->pmtud_probes,
+ sizeof(settings->pmtud_probes[0]) *
+ settings->pmtud_probeslen);
+ }
+
if (!(*pconn)->local.settings.original_version) {
(*pconn)->local.settings.original_version = client_chosen_version;
}
+ ngtcp2_dcid_init(&(*pconn)->dcid.current, 0, dcid, NULL);
+ ngtcp2_dcid_set_path(&(*pconn)->dcid.current, path);
+
+ rv = ngtcp2_gaptr_push(&(*pconn)->dcid.seqgap, 0, 1);
+ if (rv != 0) {
+ goto fail_seqgap_push;
+ }
+
conn_reset_conn_stat(*pconn, &(*pconn)->cstat);
(*pconn)->cstat.initial_rtt = settings->initial_rtt;
- (*pconn)->cstat.max_tx_udp_payload_size =
- (*pconn)->local.settings.max_tx_udp_payload_size;
ngtcp2_rst_init(&(*pconn)->rst);
@@ -1224,13 +1259,10 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
goto fail_hs_pktns_init;
}
- rv = pktns_init(&(*pconn)->pktns, NGTCP2_PKTNS_ID_APPLICATION, &(*pconn)->rst,
- &(*pconn)->cc, settings->initial_pkt_num, &(*pconn)->log,
- &(*pconn)->qlog, &(*pconn)->rtb_entry_objalloc,
- &(*pconn)->frc_objalloc, mem);
- if (rv != 0) {
- goto fail_pktns_init;
- }
+ pktns_init(&(*pconn)->pktns, NGTCP2_PKTNS_ID_APPLICATION, &(*pconn)->rst,
+ &(*pconn)->cc, settings->initial_pkt_num, &(*pconn)->log,
+ &(*pconn)->qlog, &(*pconn)->rtb_entry_objalloc,
+ &(*pconn)->frc_objalloc, mem);
scident = ngtcp2_mem_malloc(mem, sizeof(*scident));
if (scident == NULL) {
@@ -1249,14 +1281,6 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
scident = NULL;
- ngtcp2_dcid_init(&(*pconn)->dcid.current, 0, dcid, NULL);
- ngtcp2_dcid_set_path(&(*pconn)->dcid.current, path);
-
- rv = ngtcp2_gaptr_push(&(*pconn)->dcid.seqgap, 0, 1);
- if (rv != 0) {
- goto fail_seqgap_push;
- }
-
if (settings->preferred_versionslen) {
if (!server && !ngtcp2_is_reserved_version(client_chosen_version)) {
for (i = 0; i < settings->preferred_versionslen; ++i) {
@@ -1268,12 +1292,9 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
assert(i < settings->preferred_versionslen);
}
- preferred_versions = ngtcp2_mem_malloc(
- mem, sizeof(uint32_t) * settings->preferred_versionslen);
- if (preferred_versions == NULL) {
- rv = NGTCP2_ERR_NOMEM;
- goto fail_preferred_versions;
- }
+ preferred_versions = buf_align(buf);
+ buf = buf_advance(preferred_versions, sizeof(preferred_versions[0]) *
+ settings->preferred_versionslen);
for (i = 0; i < settings->preferred_versionslen; ++i) {
assert(ngtcp2_is_supported_version(settings->preferred_versions[i]));
@@ -1304,39 +1325,33 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
ngtcp2_is_supported_version(settings->available_versions[i]));
}
- rv = available_versions_new(&buf, settings->available_versions,
- settings->available_versionslen, mem);
- if (rv != 0) {
- goto fail_available_versions;
- }
-
- (*pconn)->vneg.available_versions = buf;
+ (*pconn)->vneg.available_versions = buf_align(buf);
(*pconn)->vneg.available_versionslen =
sizeof(uint32_t) * settings->available_versionslen;
+
+ buf = available_versions_init((*pconn)->vneg.available_versions,
+ settings->available_versions,
+ settings->available_versionslen);
} else if (server) {
if (settings->preferred_versionslen) {
- rv = available_versions_new(&buf, settings->preferred_versions,
- settings->preferred_versionslen, mem);
- if (rv != 0) {
- goto fail_available_versions;
- }
-
- (*pconn)->vneg.available_versions = buf;
+ (*pconn)->vneg.available_versions = buf_align(buf);
(*pconn)->vneg.available_versionslen =
sizeof(uint32_t) * settings->preferred_versionslen;
+
+ buf = available_versions_init((*pconn)->vneg.available_versions,
+ settings->preferred_versions,
+ settings->preferred_versionslen);
} else {
(*pconn)->vneg.available_versions = server_default_available_versions;
(*pconn)->vneg.available_versionslen =
sizeof(server_default_available_versions);
}
- } else if (!server && !ngtcp2_is_reserved_version(client_chosen_version)) {
- rv = available_versions_new(&buf, &client_chosen_version, 1, mem);
- if (rv != 0) {
- goto fail_available_versions;
- }
-
- (*pconn)->vneg.available_versions = buf;
+ } else if (!ngtcp2_is_reserved_version(client_chosen_version)) {
+ (*pconn)->vneg.available_versions = buf_align(buf);
(*pconn)->vneg.available_versionslen = sizeof(uint32_t);
+
+ buf = available_versions_init((*pconn)->vneg.available_versions,
+ &client_chosen_version, 1);
}
(*pconn)->local.settings.available_versions = NULL;
@@ -1377,34 +1392,19 @@ static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
return 0;
-fail_available_versions:
- ngtcp2_mem_free(mem, (*pconn)->vneg.preferred_versions);
-fail_preferred_versions:
-fail_seqgap_push:
fail_scid_set_insert:
ngtcp2_mem_free(mem, scident);
fail_scident:
- pktns_free(&(*pconn)->pktns, mem);
-fail_pktns_init:
pktns_del((*pconn)->hs_pktns, mem);
fail_hs_pktns_init:
pktns_del((*pconn)->in_pktns, mem);
fail_in_pktns_init:
+ ngtcp2_gaptr_free(&(*pconn)->dcid.seqgap);
+fail_seqgap_push:
ngtcp2_mem_free(mem, (uint8_t *)(*pconn)->local.settings.token);
fail_token:
- ngtcp2_mem_free(mem, (*pconn)->qlog.buf.begin);
-fail_qlog_buf:
- ngtcp2_idtr_free(&(*pconn)->remote.uni.idtr);
- ngtcp2_idtr_free(&(*pconn)->remote.bidi.idtr);
- ngtcp2_map_free(&(*pconn)->strms);
- delete_scid(&(*pconn)->scid.set, mem);
- ngtcp2_ksl_free(&(*pconn)->scid.set);
- ngtcp2_gaptr_free(&(*pconn)->dcid.seqgap);
- ngtcp2_objalloc_free(&(*pconn)->strm_objalloc);
- ngtcp2_objalloc_free(&(*pconn)->rtb_entry_objalloc);
- ngtcp2_objalloc_free(&(*pconn)->frc_objalloc);
ngtcp2_mem_free(mem, *pconn);
-fail_conn:
+
return rv;
}
@@ -1471,8 +1471,8 @@ int ngtcp2_conn_server_new_versioned(
* credits are considered.
*/
static uint64_t conn_fc_credits(ngtcp2_conn *conn, ngtcp2_strm *strm) {
- return ngtcp2_min(strm->tx.max_offset - strm->tx.offset,
- conn->tx.max_offset - conn->tx.offset);
+ return ngtcp2_min_uint64(strm->tx.max_offset - strm->tx.offset,
+ conn->tx.max_offset - conn->tx.offset);
}
/*
@@ -1582,11 +1582,6 @@ void ngtcp2_conn_del(ngtcp2_conn *conn) {
conn_vneg_crypto_free(conn);
- ngtcp2_mem_free(conn->mem, conn->vneg.preferred_versions);
- if (conn->vneg.available_versions != server_default_available_versions) {
- ngtcp2_mem_free(conn->mem, conn->vneg.available_versions);
- }
-
ngtcp2_mem_free(conn->mem, conn->crypto.decrypt_buf.base);
ngtcp2_mem_free(conn->mem, conn->crypto.decrypt_hp_buf.base);
ngtcp2_mem_free(conn->mem, (uint8_t *)conn->local.settings.token);
@@ -1600,8 +1595,6 @@ void ngtcp2_conn_del(ngtcp2_conn *conn) {
pktns_del(conn->hs_pktns, conn->mem);
pktns_del(conn->in_pktns, conn->mem);
- ngtcp2_mem_free(conn->mem, conn->qlog.buf.begin);
-
ngtcp2_pmtud_del(conn->pmtud);
ngtcp2_pv_del(conn->pv);
@@ -1665,8 +1658,8 @@ 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(conn->local.transport_params.max_ack_delay,
- conn->cstat.smoothed_rtt / 8);
+ return ngtcp2_min_uint64(conn->local.transport_params.max_ack_delay,
+ conn->cstat.smoothed_rtt / 8);
}
int ngtcp2_conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
@@ -2021,12 +2014,13 @@ static int conn_should_pad_pkt(ngtcp2_conn *conn, uint8_t type, size_t left,
return 0;
}
- if (conn->hs_pktns->crypto.tx.ckm &&
- (conn->hs_pktns->rtb.probe_pkt_left ||
- !ngtcp2_strm_streamfrq_empty(&conn->hs_pktns->crypto.strm) ||
- !ngtcp2_acktr_empty(&conn->hs_pktns->acktr))) {
- /* If we have something to send in Handshake packet, then add
- PADDING in Handshake packet. */
+ if ((conn->hs_pktns->crypto.tx.ckm &&
+ (conn->hs_pktns->rtb.probe_pkt_left ||
+ !ngtcp2_strm_streamfrq_empty(&conn->hs_pktns->crypto.strm) ||
+ !ngtcp2_acktr_empty(&conn->hs_pktns->acktr))) ||
+ conn->pktns.crypto.tx.ckm) {
+ /* If we have something to send in Handshake or 1RTT packet,
+ then add PADDING in that packet. */
min_payloadlen = NGTCP2_MIN_COALESCED_PAYLOADLEN;
} else {
return 1;
@@ -2195,9 +2189,10 @@ static uint8_t conn_pkt_flags_short(ngtcp2_conn *conn) {
/*
* conn_write_handshake_pkt writes handshake packet in the buffer
- * pointed by |dest| whose length is |destlen|. |type| specifies long
- * packet type. It should be either NGTCP2_PKT_INITIAL or
- * NGTCP2_PKT_HANDSHAKE_PKT.
+ * pointed by |dest| whose length is |destlen|. |dgram_offset| is the
+ * offset in UDP datagram payload where this QUIC packet is positioned
+ * at. |type| specifies long packet type. It should be either
+ * NGTCP2_PKT_INITIAL or NGTCP2_PKT_HANDSHAKE_PKT.
*
* |write_datalen| is the minimum length of application data ready to
* send in subsequent 0RTT packet.
@@ -2212,8 +2207,9 @@ static uint8_t conn_pkt_flags_short(ngtcp2_conn *conn) {
*/
static ngtcp2_ssize
conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
- size_t destlen, uint8_t type, uint8_t flags,
- uint64_t write_datalen, ngtcp2_tstamp ts) {
+ size_t destlen, size_t dgram_offset, uint8_t type,
+ uint8_t flags, uint64_t write_datalen,
+ ngtcp2_tstamp ts) {
int rv;
ngtcp2_ppe ppe;
ngtcp2_pkt_hd hd;
@@ -2282,7 +2278,7 @@ conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
hd.tokenlen = conn->local.settings.tokenlen;
}
- ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
+ ngtcp2_ppe_init(&ppe, dest, destlen, dgram_offset, &cc);
rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
if (rv != 0) {
@@ -2433,7 +2429,7 @@ conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) != 0,
require_padding)) {
lfr.type = NGTCP2_FRAME_PADDING;
- lfr.padding.len = ngtcp2_ppe_padding(&ppe);
+ lfr.padding.len = ngtcp2_ppe_dgram_padding(&ppe);
} else if (pkt_empty) {
return 0;
} else {
@@ -2602,11 +2598,7 @@ static void conn_discard_pktns(ngtcp2_conn *conn, ngtcp2_pktns **ppktns,
ngtcp2_conn_set_loss_detection_timer(conn, ts);
}
-/*
- * conn_discard_initial_state discards state for Initial packet number
- * space.
- */
-static void conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
+void ngtcp2_conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
if (!conn->in_pktns) {
return;
}
@@ -2622,11 +2614,7 @@ static void conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
memset(&conn->vneg.tx, 0, sizeof(conn->vneg.tx));
}
-/*
- * conn_discard_handshake_state discards state for Handshake packet
- * number space.
- */
-static void conn_discard_handshake_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
+void ngtcp2_conn_discard_handshake_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
if (!conn->hs_pktns) {
return;
}
@@ -2694,7 +2682,7 @@ static ngtcp2_ssize conn_write_handshake_ack_pkts(ngtcp2_conn *conn,
res += nwrite;
if (!conn->server && nwrite) {
- conn_discard_initial_state(conn, ts);
+ ngtcp2_conn_discard_initial_state(conn, ts);
}
}
@@ -2725,9 +2713,9 @@ static ngtcp2_ssize conn_write_client_initial(ngtcp2_conn *conn,
return rv;
}
- return conn_write_handshake_pkt(conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
- NGTCP2_WRITE_PKT_FLAG_NONE, early_datalen,
- ts);
+ return conn_write_handshake_pkt(
+ conn, pi, dest, destlen, 0, NGTCP2_PKT_INITIAL,
+ NGTCP2_WRITE_PKT_FLAG_NONE, early_datalen, ts);
}
/*
@@ -2807,10 +2795,10 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
conn->hs_pktns->rtb.probe_pkt_left)) {
/* Discard Initial state here so that Handshake packet is not
padded. */
- conn_discard_initial_state(conn, ts);
+ ngtcp2_conn_discard_initial_state(conn, ts);
} else if (conn->in_pktns) {
nwrite =
- conn_write_handshake_pkt(conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
+ conn_write_handshake_pkt(conn, pi, dest, destlen, 0, NGTCP2_PKT_INITIAL,
NGTCP2_WRITE_PKT_FLAG_NONE, write_datalen, ts);
if (nwrite < 0) {
assert(nwrite != NGTCP2_ERR_NOBUF);
@@ -2837,10 +2825,10 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
dest += nwrite;
destlen -= (size_t)nwrite;
- if (destlen) {
- /* We might have already added padding to Initial, but in that
- case, we should have destlen == 0 and no Handshake packet
- will be written. */
+ /* If initial packet size is at least
+ NGTCP2_MAX_UDP_PAYLOAD_SIZE, no extra padding is needed in a
+ subsequent packet. */
+ if (nwrite < NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
if (conn->server) {
it = ngtcp2_rtb_head(&conn->in_pktns->rtb);
if (!ngtcp2_ksl_it_end(&it)) {
@@ -2856,8 +2844,9 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
}
}
- nwrite = conn_write_handshake_pkt(
- conn, pi, dest, destlen, NGTCP2_PKT_HANDSHAKE, wflags, write_datalen, ts);
+ nwrite =
+ conn_write_handshake_pkt(conn, pi, dest, destlen, (size_t)res,
+ NGTCP2_PKT_HANDSHAKE, wflags, write_datalen, ts);
if (nwrite < 0) {
assert(nwrite != NGTCP2_ERR_NOBUF);
return nwrite;
@@ -2869,7 +2858,7 @@ static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
/* We don't need to send further Initial packet if we have
Handshake key and sent something with it. So discard initial
state here. */
- conn_discard_initial_state(conn, ts);
+ ngtcp2_conn_discard_initial_state(conn, ts);
}
return res;
@@ -3097,7 +3086,8 @@ static int conn_remove_retired_connection_id(ngtcp2_conn *conn,
* this endpoint sends.
*/
static size_t conn_min_short_pktlen(ngtcp2_conn *conn) {
- return conn->dcid.current.cid.datalen + NGTCP2_MIN_PKT_EXPANDLEN;
+ return ngtcp2_max(conn->dcid.current.cid.datalen, conn->oscid.datalen) +
+ NGTCP2_MIN_PKT_EXPANDLEN;
}
/*
@@ -3155,8 +3145,10 @@ static void conn_reset_ppe_pending(ngtcp2_conn *conn) {
/*
* conn_write_pkt writes a protected packet in the buffer pointed by
- * |dest| whose length if |destlen|. |type| specifies the type of
- * packet. It can be NGTCP2_PKT_1RTT or NGTCP2_PKT_0RTT.
+ * |dest| whose length if |destlen|. |dgram_offset| is the offset in
+ * UDP datagram payload where this QUIC packet is positioned at.
+ * |type| specifies the type of packet. It can be NGTCP2_PKT_1RTT or
+ * NGTCP2_PKT_0RTT.
*
* This function can send new stream data. In order to send stream
* data, specify the underlying stream and parameters to
@@ -3183,8 +3175,9 @@ static void conn_reset_ppe_pending(ngtcp2_conn *conn) {
*/
static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
uint8_t *dest, size_t destlen,
- ngtcp2_vmsg *vmsg, uint8_t type,
- uint8_t flags, ngtcp2_tstamp ts) {
+ size_t dgram_offset, ngtcp2_vmsg *vmsg,
+ uint8_t type, uint8_t flags,
+ ngtcp2_tstamp ts) {
int rv = 0;
ngtcp2_crypto_cc *cc = &conn->pkt.cc;
ngtcp2_ppe *ppe = &conn->pkt.ppe;
@@ -3369,7 +3362,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
pktns->tx.last_pkt_num + 1,
pktns_select_pkt_numlen(pktns), version, 0);
- ngtcp2_ppe_init(ppe, dest, destlen, cc);
+ ngtcp2_ppe_init(ppe, dest, destlen, dgram_offset, cc);
rv = ngtcp2_ppe_encode_hd(ppe, hd);
if (rv != 0) {
@@ -3944,6 +3937,7 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
vmsg->stream.strm->tx.offset += ndatalen;
conn->tx.offset += ndatalen;
+ vmsg->stream.strm->flags |= NGTCP2_STRM_FLAG_ANY_SENT;
if (fin) {
ngtcp2_strm_shutdown(vmsg->stream.strm, NGTCP2_STRM_FLAG_SHUT_WR);
@@ -4166,10 +4160,8 @@ static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
/* TODO Push STREAM frame back to ngtcp2_strm if there is an error
before ngtcp2_rtb_entry is safely created and added. */
- if (require_padding ||
- /* Making full sized packet will help GSO a bit */
- ngtcp2_ppe_left(ppe) < 10) {
- lfr.padding.len = ngtcp2_ppe_padding(ppe);
+ if (require_padding) {
+ lfr.padding.len = ngtcp2_ppe_dgram_padding(ppe);
} else if (type == NGTCP2_PKT_1RTT) {
lfr.padding.len = ngtcp2_ppe_padding_size(ppe, min_pktlen);
} else {
@@ -4332,7 +4324,7 @@ ngtcp2_ssize ngtcp2_conn_write_single_frame_pkt(
pktns->tx.last_pkt_num + 1, pktns_select_pkt_numlen(pktns),
version, 0);
- ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
+ ngtcp2_ppe_init(&ppe, dest, destlen, 0, &cc);
rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
if (rv != 0) {
@@ -4354,14 +4346,16 @@ ngtcp2_ssize ngtcp2_conn_write_single_frame_pkt(
}
lfr.type = NGTCP2_FRAME_PADDING;
- if (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING) {
- lfr.padding.len = ngtcp2_ppe_padding(&ppe);
+ if (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING_FULL) {
+ lfr.padding.len = ngtcp2_ppe_dgram_padding_size(&ppe, destlen);
+ } else if (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING) {
+ lfr.padding.len = ngtcp2_ppe_dgram_padding(&ppe);
} else {
switch (fr->type) {
case NGTCP2_FRAME_PATH_CHALLENGE:
case NGTCP2_FRAME_PATH_RESPONSE:
if (!conn->server || destlen >= NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
- lfr.padding.len = ngtcp2_ppe_padding(&ppe);
+ lfr.padding.len = ngtcp2_ppe_dgram_padding(&ppe);
} else {
lfr.padding.len = 0;
}
@@ -4522,6 +4516,10 @@ static int conn_retire_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
ngtcp2_frame_chain *nfrc;
int rv;
+ if (ngtcp2_conn_check_retired_dcid_tracked(conn, seq)) {
+ return 0;
+ }
+
rv = ngtcp2_conn_track_retired_dcid_seq(conn, seq);
if (rv != 0) {
return rv;
@@ -4664,7 +4662,9 @@ static int conn_start_pmtud(ngtcp2_conn *conn) {
rv = ngtcp2_pmtud_new(&conn->pmtud, conn->dcid.current.max_udp_payload_size,
hard_max_udp_payload_size,
- conn->pktns.tx.last_pkt_num + 1, conn->mem);
+ conn->pktns.tx.last_pkt_num + 1,
+ conn->local.settings.pmtud_probes,
+ conn->local.settings.pmtud_probeslen, conn->mem);
if (rv != 0) {
return rv;
}
@@ -4716,7 +4716,7 @@ static ngtcp2_ssize conn_write_pmtud_probe(ngtcp2_conn *conn,
nwrite = ngtcp2_conn_write_single_frame_pkt(
conn, pi, dest, probelen, NGTCP2_PKT_1RTT,
- NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING, &conn->dcid.current.cid, &lfr,
+ NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING_FULL, &conn->dcid.current.cid, &lfr,
NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE,
@@ -6833,6 +6833,12 @@ static int conn_emit_pending_stream_data(ngtcp2_conn *conn, ngtcp2_strm *strm,
return rv;
}
+ /* ngtcp2_conn_shutdown_stream_read from a callback will free
+ strm->rx.rob. */
+ if (!strm->rx.rob) {
+ return 0;
+ }
+
ngtcp2_rob_pop(strm->rx.rob, rx_offset - datalen, datalen);
}
}
@@ -8221,7 +8227,7 @@ static int conn_recv_handshake_done(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
conn->pktns.rtb.persistent_congestion_start_ts = ts;
- conn_discard_handshake_state(conn, ts);
+ ngtcp2_conn_discard_handshake_state(conn, ts);
assert(conn->remote.transport_params);
@@ -8550,13 +8556,13 @@ static int conn_recv_non_probing_pkt_on_new_path(ngtcp2_conn *conn,
pv->fallback_pto = pto;
}
+ ngtcp2_dcid_copy(&conn->dcid.current, &dcid);
+
if (!local_addr_eq || (remote_addr_cmp & (NGTCP2_ADDR_COMPARE_FLAG_ADDR |
NGTCP2_ADDR_COMPARE_FLAG_FAMILY))) {
conn_reset_congestion_state(conn, ts);
}
- ngtcp2_dcid_copy(&conn->dcid.current, &dcid);
-
conn_reset_ecn_validation_state(conn);
ngtcp2_conn_stop_pmtud(conn);
@@ -9822,7 +9828,7 @@ static ngtcp2_ssize conn_read_handshake(ngtcp2_conn *conn,
}
if (conn->hs_pktns->rx.max_pkt_num != -1) {
- conn_discard_initial_state(conn, ts);
+ ngtcp2_conn_discard_initial_state(conn, ts);
}
if (!conn_is_tls_handshake_completed(conn)) {
@@ -9888,7 +9894,7 @@ static ngtcp2_ssize conn_read_handshake(ngtcp2_conn *conn,
return rv;
}
- conn_discard_handshake_state(conn, ts);
+ ngtcp2_conn_discard_handshake_state(conn, ts);
rv = conn_enqueue_handshake_done(conn);
if (rv != 0) {
@@ -9936,7 +9942,7 @@ int ngtcp2_conn_read_pkt_versioned(ngtcp2_conn *conn, const ngtcp2_path *path,
pktlen);
if (pktlen == 0) {
- return NGTCP2_ERR_INVALID_ARGUMENT;
+ return 0;
}
/* client does not expect a packet from unknown path. */
@@ -10035,13 +10041,12 @@ static int conn_check_pkt_num_exhausted(ngtcp2_conn *conn) {
* conn_retransmit_retry_early retransmits 0RTT packet after Retry is
* received from server.
*/
-static ngtcp2_ssize conn_retransmit_retry_early(ngtcp2_conn *conn,
- ngtcp2_pkt_info *pi,
- uint8_t *dest, size_t destlen,
- uint8_t flags,
- ngtcp2_tstamp ts) {
- return conn_write_pkt(conn, pi, dest, destlen, NULL, NGTCP2_PKT_0RTT, flags,
- ts);
+static ngtcp2_ssize
+conn_retransmit_retry_early(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
+ uint8_t *dest, size_t destlen, size_t dgram_offset,
+ uint8_t flags, ngtcp2_tstamp ts) {
+ return conn_write_pkt(conn, pi, dest, destlen, dgram_offset, NULL,
+ NGTCP2_PKT_0RTT, flags, ts);
}
/*
@@ -10137,7 +10142,7 @@ static ngtcp2_ssize conn_write_handshake(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
}
} else {
nwrite = conn_write_handshake_pkt(
- conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
+ conn, pi, dest, destlen, 0, NGTCP2_PKT_INITIAL,
NGTCP2_WRITE_PKT_FLAG_NONE, write_datalen, ts);
if (nwrite < 0) {
return nwrite;
@@ -10146,7 +10151,7 @@ static ngtcp2_ssize conn_write_handshake(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
if (pending_early_datalen) {
early_spktlen = conn_retransmit_retry_early(
- conn, pi, dest + nwrite, destlen - (size_t)nwrite,
+ conn, pi, dest + nwrite, destlen - (size_t)nwrite, (size_t)nwrite,
nwrite ? NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING
: NGTCP2_WRITE_PKT_FLAG_NONE,
ts);
@@ -10186,8 +10191,9 @@ static ngtcp2_ssize conn_write_handshake(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
if (!conn_is_tls_handshake_completed(conn)) {
if (!(conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED)) {
- nwrite = conn_retransmit_retry_early(conn, pi, dest, destlen,
- NGTCP2_WRITE_PKT_FLAG_NONE, ts);
+ nwrite =
+ conn_retransmit_retry_early(conn, pi, dest, destlen, (size_t)res,
+ NGTCP2_WRITE_PKT_FLAG_NONE, ts);
if (nwrite < 0) {
return nwrite;
}
@@ -10363,8 +10369,8 @@ static ngtcp2_ssize conn_client_write_handshake(ngtcp2_conn *conn,
datalen = ngtcp2_vec_len(vmsg->stream.data, vmsg->stream.datacnt);
send_stream = conn_retry_early_payloadlen(conn) == 0;
if (send_stream) {
- write_datalen = ngtcp2_min(datalen + NGTCP2_STREAM_OVERHEAD,
- NGTCP2_MIN_COALESCED_PAYLOADLEN);
+ write_datalen = ngtcp2_min_uint64(datalen + NGTCP2_STREAM_OVERHEAD,
+ NGTCP2_MIN_COALESCED_PAYLOADLEN);
if (vmsg->stream.flags & NGTCP2_WRITE_STREAM_FLAG_MORE) {
wflags |= NGTCP2_WRITE_PKT_FLAG_MORE;
@@ -10428,8 +10434,8 @@ static ngtcp2_ssize conn_client_write_handshake(ngtcp2_conn *conn,
return spktlen;
}
- early_spktlen = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_0RTT,
- wflags, ts);
+ early_spktlen = conn_write_pkt(conn, pi, dest, destlen, (size_t)spktlen, vmsg,
+ NGTCP2_PKT_0RTT, wflags, ts);
if (early_spktlen < 0) {
switch (early_spktlen) {
case NGTCP2_ERR_STREAM_DATA_BLOCKED:
@@ -10905,7 +10911,7 @@ ngtcp2_tstamp ngtcp2_conn_loss_detection_expiry(ngtcp2_conn *conn) {
}
ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn) {
- ngtcp2_tstamp res = UINT64_MAX, t;
+ ngtcp2_tstamp res = UINT64_MAX;
ngtcp2_duration pto = conn_compute_pto(conn, &conn->pktns);
ngtcp2_scid *scid;
ngtcp2_dcid *dcid;
@@ -10922,15 +10928,13 @@ ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn) {
if (!ngtcp2_pq_empty(&conn->scid.used)) {
scid = ngtcp2_struct_of(ngtcp2_pq_top(&conn->scid.used), ngtcp2_scid, pe);
if (scid->retired_ts != UINT64_MAX) {
- t = scid->retired_ts + pto;
- res = ngtcp2_min(res, t);
+ res = ngtcp2_min_uint64(res, scid->retired_ts + pto);
}
}
if (ngtcp2_ringbuf_len(&conn->dcid.retired.rb)) {
dcid = ngtcp2_ringbuf_get(&conn->dcid.retired.rb, 0);
- t = dcid->retired_ts + pto;
- res = ngtcp2_min(res, t);
+ res = ngtcp2_min_uint64(res, dcid->retired_ts + pto);
}
if (conn->dcid.current.cid.datalen) {
@@ -10941,15 +10945,13 @@ ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn) {
assert(dcid->cid.datalen);
assert(dcid->bound_ts != UINT64_MAX);
- t = dcid->bound_ts + 3 * pto;
- res = ngtcp2_min(res, t);
+ res = ngtcp2_min_uint64(res, dcid->bound_ts + 3 * pto);
}
}
if (conn->server && conn->early.ckm &&
conn->early.discard_started_ts != UINT64_MAX) {
- t = conn->early.discard_started_ts + 3 * pto;
- res = ngtcp2_min(res, t);
+ res = ngtcp2_min_uint64(res, conn->early.discard_started_ts + 3 * pto);
}
return res;
@@ -10978,19 +10980,13 @@ static ngtcp2_tstamp conn_handshake_expiry(ngtcp2_conn *conn) {
}
ngtcp2_tstamp ngtcp2_conn_get_expiry(ngtcp2_conn *conn) {
- ngtcp2_tstamp t1 = ngtcp2_conn_loss_detection_expiry(conn);
- ngtcp2_tstamp t2 = ngtcp2_conn_ack_delay_expiry(conn);
- ngtcp2_tstamp t3 = ngtcp2_conn_internal_expiry(conn);
- ngtcp2_tstamp t4 = ngtcp2_conn_lost_pkt_expiry(conn);
- ngtcp2_tstamp t5 = conn_keep_alive_expiry(conn);
- ngtcp2_tstamp t6 = conn_handshake_expiry(conn);
- ngtcp2_tstamp t7 = ngtcp2_conn_get_idle_expiry(conn);
- ngtcp2_tstamp res = ngtcp2_min(t1, t2);
- res = ngtcp2_min(res, t3);
- res = ngtcp2_min(res, t4);
- res = ngtcp2_min(res, t5);
- res = ngtcp2_min(res, t6);
- res = ngtcp2_min(res, t7);
+ ngtcp2_tstamp res = ngtcp2_min_uint64(ngtcp2_conn_loss_detection_expiry(conn),
+ ngtcp2_conn_ack_delay_expiry(conn));
+ res = ngtcp2_min_uint64(res, ngtcp2_conn_internal_expiry(conn));
+ res = ngtcp2_min_uint64(res, ngtcp2_conn_lost_pkt_expiry(conn));
+ res = ngtcp2_min_uint64(res, conn_keep_alive_expiry(conn));
+ res = ngtcp2_min_uint64(res, conn_handshake_expiry(conn));
+ res = ngtcp2_min_uint64(res, ngtcp2_conn_get_idle_expiry(conn));
return ngtcp2_min(res, conn->tx.pacing.next_ts);
}
@@ -11734,19 +11730,24 @@ ngtcp2_ssize ngtcp2_conn_writev_stream_versioned(
return NGTCP2_ERR_INVALID_ARGUMENT;
}
- if ((uint64_t)datalen > NGTCP2_MAX_VARINT - strm->tx.offset ||
- (uint64_t)datalen > NGTCP2_MAX_VARINT - conn->tx.offset) {
- return NGTCP2_ERR_INVALID_ARGUMENT;
- }
+ if (datalen == 0 && !(flags & NGTCP2_WRITE_STREAM_FLAG_FIN) &&
+ (strm->flags & NGTCP2_STRM_FLAG_ANY_SENT)) {
+ pvmsg = NULL;
+ } else {
+ if ((uint64_t)datalen > NGTCP2_MAX_VARINT - strm->tx.offset ||
+ (uint64_t)datalen > NGTCP2_MAX_VARINT - conn->tx.offset) {
+ return NGTCP2_ERR_INVALID_ARGUMENT;
+ }
- vmsg.type = NGTCP2_VMSG_TYPE_STREAM;
- vmsg.stream.strm = strm;
- vmsg.stream.flags = flags;
- vmsg.stream.data = datav;
- vmsg.stream.datacnt = datavcnt;
- vmsg.stream.pdatalen = pdatalen;
+ vmsg.type = NGTCP2_VMSG_TYPE_STREAM;
+ vmsg.stream.strm = strm;
+ vmsg.stream.flags = flags;
+ vmsg.stream.data = datav;
+ vmsg.stream.datacnt = datavcnt;
+ vmsg.stream.pdatalen = pdatalen;
- pvmsg = &vmsg;
+ pvmsg = &vmsg;
+ }
} else {
pvmsg = NULL;
}
@@ -11867,10 +11868,9 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
assert(dest[0] & NGTCP2_HEADER_FORM_BIT);
assert(conn->negotiated_version);
- if (ngtcp2_pkt_get_type_long(conn->negotiated_version, dest[0]) ==
- NGTCP2_PKT_INITIAL) {
- /* We have added padding already, but in that case, there is no
- space left to write 1RTT packet. */
+ if (nwrite < NGTCP2_MAX_UDP_PAYLOAD_SIZE &&
+ ngtcp2_pkt_get_type_long(conn->negotiated_version, dest[0]) ==
+ NGTCP2_PKT_INITIAL) {
wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
}
@@ -11931,14 +11931,12 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
dest += nwrite;
destlen -= (size_t)nwrite;
- if (conn->in_pktns && nwrite > 0) {
+ if (res < NGTCP2_MAX_UDP_PAYLOAD_SIZE && conn->in_pktns && nwrite > 0) {
it = ngtcp2_rtb_head(&conn->in_pktns->rtb);
if (!ngtcp2_ksl_it_end(&it)) {
rtbent = ngtcp2_ksl_it_get(&it);
if (rtbent->hd.pkt_num != prev_in_pkt_num &&
(rtbent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
- /* We have added padding already, but in that case, there
- is no space left to write 1RTT packet. */
wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
}
}
@@ -12004,8 +12002,8 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
}
/* dest and destlen have already been adjusted in ppe in the first
run. They are adjusted for probe packet later. */
- nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
- wflags, ts);
+ nwrite = conn_write_pkt(conn, pi, dest, destlen, (size_t)res, vmsg,
+ NGTCP2_PKT_1RTT, wflags, ts);
goto fin;
} else {
conn->pkt.require_padding =
@@ -12100,14 +12098,14 @@ ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
"transmit probe pkt left=%zu",
conn->pktns.rtb.probe_pkt_left);
- nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
- wflags, ts);
+ nwrite = conn_write_pkt(conn, pi, dest, destlen, (size_t)res, vmsg,
+ NGTCP2_PKT_1RTT, wflags, ts);
goto fin;
}
- nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
- wflags, ts);
+ nwrite = conn_write_pkt(conn, pi, dest, destlen, (size_t)res, vmsg,
+ NGTCP2_PKT_1RTT, wflags, ts);
if (nwrite) {
assert(nwrite != NGTCP2_ERR_NOBUF);
goto fin;
@@ -12326,12 +12324,9 @@ ngtcp2_ssize ngtcp2_conn_write_application_close_pkt(
destlen -= (size_t)nwrite;
}
- if (conn->state != NGTCP2_CS_POST_HANDSHAKE) {
- assert(res);
-
- if (!conn->server || !conn->pktns.crypto.tx.ckm) {
- return res;
- }
+ if (conn->state != NGTCP2_CS_POST_HANDSHAKE &&
+ (!conn->server || !conn->pktns.crypto.tx.ckm)) {
+ return res;
}
assert(conn->pktns.crypto.tx.ckm);
@@ -12393,6 +12388,16 @@ void ngtcp2_ccerr_set_liberr(ngtcp2_ccerr *ccerr, int liberr,
reasonlen);
return;
+ case NGTCP2_ERR_DROP_CONN:
+ ccerr_init(ccerr, NGTCP2_CCERR_TYPE_DROP_CONN, NGTCP2_NO_ERROR, reason,
+ reasonlen);
+
+ return;
+ case NGTCP2_ERR_RETRY:
+ ccerr_init(ccerr, NGTCP2_CCERR_TYPE_RETRY, NGTCP2_NO_ERROR, reason,
+ reasonlen);
+
+ return;
};
ngtcp2_ccerr_set_transport_error(
@@ -13597,20 +13602,11 @@ size_t ngtcp2_conn_get_send_quantum(ngtcp2_conn *conn) {
}
int ngtcp2_conn_track_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
- size_t i;
-
if (conn->dcid.retire_unacked.len >=
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) {
- ngtcp2_unreachable();
- }
- }
-
conn->dcid.retire_unacked.seqs[conn->dcid.retire_unacked.len++] = seq;
return 0;
@@ -13635,6 +13631,18 @@ void ngtcp2_conn_untrack_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
}
}
+int ngtcp2_conn_check_retired_dcid_tracked(ngtcp2_conn *conn, uint64_t seq) {
+ size_t i;
+
+ for (i = 0; i < conn->dcid.retire_unacked.len; ++i) {
+ if (conn->dcid.retire_unacked.seqs[i] == seq) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
size_t ngtcp2_conn_get_stream_loss_count(ngtcp2_conn *conn, int64_t stream_id) {
ngtcp2_strm *strm = ngtcp2_conn_find_stream(conn, stream_id);
@@ -13652,45 +13660,6 @@ void ngtcp2_path_challenge_entry_init(ngtcp2_path_challenge_entry *pcent,
memcpy(pcent->data, data, sizeof(pcent->data));
}
-void ngtcp2_settings_default_versioned(int settings_version,
- ngtcp2_settings *settings) {
- (void)settings_version;
-
- memset(settings, 0, sizeof(*settings));
- settings->cc_algo = NGTCP2_CC_ALGO_CUBIC;
- settings->initial_rtt = NGTCP2_DEFAULT_INITIAL_RTT;
- settings->ack_thresh = 2;
- settings->max_tx_udp_payload_size = 1500 - 48;
- settings->handshake_timeout = UINT64_MAX;
-}
-
-void ngtcp2_transport_params_default_versioned(
- int transport_params_version, ngtcp2_transport_params *params) {
- size_t len;
-
- switch (transport_params_version) {
- case NGTCP2_TRANSPORT_PARAMS_VERSION:
- len = sizeof(*params);
-
- break;
- default:
- ngtcp2_unreachable();
- }
-
- memset(params, 0, len);
-
- switch (transport_params_version) {
- case NGTCP2_TRANSPORT_PARAMS_VERSION:
- params->max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE;
- params->active_connection_id_limit =
- NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
- params->ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
- params->max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
-
- break;
- }
-}
-
/* The functions prefixed with ngtcp2_pkt_ are usually put inside
ngtcp2_pkt.c. This function uses encryption construct and uses
test data defined only in ngtcp2_conn_test.c, so it is written
@@ -13726,7 +13695,7 @@ ngtcp2_ssize ngtcp2_pkt_write_connection_close(
cc.encrypt = encrypt;
cc.hp_mask = hp_mask;
- ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
+ ngtcp2_ppe_init(&ppe, dest, destlen, 0, &cc);
rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
if (rv != 0) {