#include <gnutls/crypto.h>
#include <string.h>
+#include "ngtcp2_macro.h"
#include "shared.h"
ngtcp2_crypto_aead *ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead *aead) {
gnutls_cipher_set_iv(hd, (void *)sample, 16);
- if (gnutls_cipher_encrypt2(hd, PLAINTEXT, sizeof(PLAINTEXT) - 1, buf,
+ if (gnutls_cipher_encrypt2(hd, PLAINTEXT, ngtcp2_strlen_lit(PLAINTEXT), buf,
buflen) != 0) {
return -1;
}
*p++ = (uint8_t)(destlen / 256);
*p++ = (uint8_t)(destlen % 256);
- *p++ = (uint8_t)(sizeof(LABEL) - 1 + labellen);
- memcpy(p, LABEL, sizeof(LABEL) - 1);
- p += sizeof(LABEL) - 1;
+ *p++ = (uint8_t)(ngtcp2_strlen_lit(LABEL) + labellen);
+ memcpy(p, LABEL, ngtcp2_strlen_lit(LABEL));
+ p += ngtcp2_strlen_lit(LABEL);
memcpy(p, label, labellen);
p += labellen;
*p++ = 0;
case NGTCP2_PROTO_VER_V1:
default:
salt = (const uint8_t *)NGTCP2_INITIAL_SALT_V1;
- saltlen = sizeof(NGTCP2_INITIAL_SALT_V1) - 1;
+ saltlen = ngtcp2_strlen_lit(NGTCP2_INITIAL_SALT_V1);
break;
case NGTCP2_PROTO_VER_V2:
salt = (const uint8_t *)NGTCP2_INITIAL_SALT_V2;
- saltlen = sizeof(NGTCP2_INITIAL_SALT_V2) - 1;
+ saltlen = ngtcp2_strlen_lit(NGTCP2_INITIAL_SALT_V2);
break;
}
if (ngtcp2_crypto_hkdf_expand_label(
client_secret, NGTCP2_CRYPTO_INITIAL_SECRETLEN, &ctx.md, initial_secret,
- NGTCP2_CRYPTO_INITIAL_SECRETLEN, CLABEL, sizeof(CLABEL) - 1) != 0 ||
+ NGTCP2_CRYPTO_INITIAL_SECRETLEN, CLABEL,
+ ngtcp2_strlen_lit(CLABEL)) != 0 ||
ngtcp2_crypto_hkdf_expand_label(
server_secret, NGTCP2_CRYPTO_INITIAL_SECRETLEN, &ctx.md, initial_secret,
- NGTCP2_CRYPTO_INITIAL_SECRETLEN, SLABEL, sizeof(SLABEL) - 1) != 0) {
+ NGTCP2_CRYPTO_INITIAL_SECRETLEN, SLABEL,
+ ngtcp2_strlen_lit(SLABEL)) != 0) {
return -1;
}
switch (version) {
case NGTCP2_PROTO_VER_V2:
key_label = KEY_LABEL_V2;
- key_labellen = sizeof(KEY_LABEL_V2) - 1;
+ key_labellen = ngtcp2_strlen_lit(KEY_LABEL_V2);
iv_label = IV_LABEL_V2;
- iv_labellen = sizeof(IV_LABEL_V2) - 1;
+ iv_labellen = ngtcp2_strlen_lit(IV_LABEL_V2);
hp_key_label = HP_KEY_LABEL_V2;
- hp_key_labellen = sizeof(HP_KEY_LABEL_V2) - 1;
+ hp_key_labellen = ngtcp2_strlen_lit(HP_KEY_LABEL_V2);
break;
default:
key_label = KEY_LABEL_V1;
- key_labellen = sizeof(KEY_LABEL_V1) - 1;
+ key_labellen = ngtcp2_strlen_lit(KEY_LABEL_V1);
iv_label = IV_LABEL_V1;
- iv_labellen = sizeof(IV_LABEL_V1) - 1;
+ iv_labellen = ngtcp2_strlen_lit(IV_LABEL_V1);
hp_key_label = HP_KEY_LABEL_V1;
- hp_key_labellen = sizeof(HP_KEY_LABEL_V1) - 1;
+ hp_key_labellen = ngtcp2_strlen_lit(HP_KEY_LABEL_V1);
}
if (ngtcp2_crypto_hkdf_expand_label(key, keylen, md, secret, secretlen,
switch (version) {
case NGTCP2_PROTO_VER_V2:
label = LABEL_V2;
- labellen = sizeof(LABEL_V2) - 1;
+ labellen = ngtcp2_strlen_lit(LABEL_V2);
break;
default:
label = LABEL;
- labellen = sizeof(LABEL) - 1;
+ labellen = ngtcp2_strlen_lit(LABEL);
}
if (ngtcp2_crypto_hkdf_expand_label(dest, secretlen, md, secret, secretlen,
case NGTCP2_PROTO_VER_V1:
default:
retry_key = (const uint8_t *)NGTCP2_RETRY_KEY_V1;
- retry_noncelen = sizeof(NGTCP2_RETRY_NONCE_V1) - 1;
+ retry_noncelen = ngtcp2_strlen_lit(NGTCP2_RETRY_NONCE_V1);
break;
case NGTCP2_PROTO_VER_V2:
retry_key = (const uint8_t *)NGTCP2_RETRY_KEY_V2;
- retry_noncelen = sizeof(NGTCP2_RETRY_NONCE_V2) - 1;
+ retry_noncelen = ngtcp2_strlen_lit(NGTCP2_RETRY_NONCE_V2);
break;
}
if (ngtcp2_crypto_hkdf(token, NGTCP2_STATELESS_RESET_TOKENLEN,
ngtcp2_crypto_md_sha256(&md), secret, secretlen,
cid->data, cid->datalen, info,
- sizeof(info) - 1) != 0) {
+ ngtcp2_strlen_lit(info)) != 0) {
return -1;
}
uint8_t *p;
assert(ngtcp2_crypto_md_hashlen(md) == sizeof(intsecret));
- assert(info_prefixlen + sizeof(key_info_suffix) - 1 <= sizeof(info));
- assert(info_prefixlen + sizeof(iv_info_suffix) - 1 <= sizeof(info));
+ assert(info_prefixlen + ngtcp2_strlen_lit(key_info_suffix) <= sizeof(info));
+ assert(info_prefixlen + ngtcp2_strlen_lit(iv_info_suffix) <= sizeof(info));
if (ngtcp2_crypto_hkdf_extract(intsecret, md, secret, secretlen, salt,
saltlen) != 0) {
memcpy(info, info_prefix, info_prefixlen);
p = info + info_prefixlen;
- memcpy(p, key_info_suffix, sizeof(key_info_suffix) - 1);
- p += sizeof(key_info_suffix) - 1;
+ memcpy(p, key_info_suffix, ngtcp2_strlen_lit(key_info_suffix));
+ p += ngtcp2_strlen_lit(key_info_suffix);
if (ngtcp2_crypto_hkdf_expand(key, keylen, md, intsecret, sizeof(intsecret),
info, (size_t)(p - info)) != 0) {
p = info + info_prefixlen;
- memcpy(p, iv_info_suffix, sizeof(iv_info_suffix) - 1);
- p += sizeof(iv_info_suffix) - 1;
+ memcpy(p, iv_info_suffix, ngtcp2_strlen_lit(iv_info_suffix));
+ p += ngtcp2_strlen_lit(iv_info_suffix);
if (ngtcp2_crypto_hkdf_expand(iv, ivlen, md, intsecret, sizeof(intsecret),
info, (size_t)(p - info)) != 0) {
assert(sizeof(key) == keylen);
assert(sizeof(iv) == ivlen);
- if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
- rand_data, sizeof(rand_data),
- retry_token_info_prefix,
- sizeof(retry_token_info_prefix) - 1) != 0) {
+ if (crypto_derive_token_key(
+ key, keylen, iv, ivlen, &md, secret, secretlen, rand_data,
+ sizeof(rand_data), retry_token_info_prefix,
+ ngtcp2_strlen_lit(retry_token_info_prefix)) != 0) {
return -1;
}
assert(sizeof(key) == keylen);
assert(sizeof(iv) == ivlen);
- if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
- rand_data, NGTCP2_CRYPTO_TOKEN_RAND_DATALEN,
- retry_token_info_prefix,
- sizeof(retry_token_info_prefix) - 1) != 0) {
+ if (crypto_derive_token_key(
+ key, keylen, iv, ivlen, &md, secret, secretlen, rand_data,
+ NGTCP2_CRYPTO_TOKEN_RAND_DATALEN, retry_token_info_prefix,
+ ngtcp2_strlen_lit(retry_token_info_prefix)) != 0) {
return -1;
}
assert(sizeof(key) == keylen);
assert(sizeof(iv) == ivlen);
- if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
- rand_data, sizeof(rand_data),
- retry_token_info_prefix2,
- sizeof(retry_token_info_prefix2) - 1) != 0) {
+ if (crypto_derive_token_key(
+ key, keylen, iv, ivlen, &md, secret, secretlen, rand_data,
+ sizeof(rand_data), retry_token_info_prefix2,
+ ngtcp2_strlen_lit(retry_token_info_prefix2)) != 0) {
return -1;
}
assert(sizeof(key) == keylen);
assert(sizeof(iv) == ivlen);
- if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
- rand_data, NGTCP2_CRYPTO_TOKEN_RAND_DATALEN,
- retry_token_info_prefix2,
- sizeof(retry_token_info_prefix2) - 1) != 0) {
+ if (crypto_derive_token_key(
+ key, keylen, iv, ivlen, &md, secret, secretlen, rand_data,
+ NGTCP2_CRYPTO_TOKEN_RAND_DATALEN, retry_token_info_prefix2,
+ ngtcp2_strlen_lit(retry_token_info_prefix2)) != 0) {
return NGTCP2_CRYPTO_ERR_INTERNAL;
}
assert(sizeof(key) == keylen);
assert(sizeof(iv) == ivlen);
- if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
- rand_data, sizeof(rand_data),
- regular_token_info_prefix,
- sizeof(regular_token_info_prefix) - 1) != 0) {
+ if (crypto_derive_token_key(
+ key, keylen, iv, ivlen, &md, secret, secretlen, rand_data,
+ sizeof(rand_data), regular_token_info_prefix,
+ ngtcp2_strlen_lit(regular_token_info_prefix)) != 0) {
return -1;
}
assert(sizeof(key) == keylen);
assert(sizeof(iv) == ivlen);
- if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
- rand_data, NGTCP2_CRYPTO_TOKEN_RAND_DATALEN,
- regular_token_info_prefix,
- sizeof(regular_token_info_prefix) - 1) != 0) {
+ if (crypto_derive_token_key(
+ key, keylen, iv, ivlen, &md, secret, secretlen, rand_data,
+ NGTCP2_CRYPTO_TOKEN_RAND_DATALEN, regular_token_info_prefix,
+ ngtcp2_strlen_lit(regular_token_info_prefix)) != 0) {
return NGTCP2_CRYPTO_ERR_INTERNAL;
}
case NGTCP2_PROTO_VER_V1:
default:
key = (const uint8_t *)NGTCP2_RETRY_KEY_V1;
- noncelen = sizeof(NGTCP2_RETRY_NONCE_V1) - 1;
+ noncelen = ngtcp2_strlen_lit(NGTCP2_RETRY_NONCE_V1);
break;
case NGTCP2_PROTO_VER_V2:
key = (const uint8_t *)NGTCP2_RETRY_KEY_V2;
- noncelen = sizeof(NGTCP2_RETRY_NONCE_V2) - 1;
+ noncelen = ngtcp2_strlen_lit(NGTCP2_RETRY_NONCE_V2);
break;
}
packet number. */
ngtcp2_ksl ents;
ngtcp2_log *log;
- /* flags is bitwise OR of zero, or more of NGTCP2_ACKTR_FLAG_*. */
- uint16_t flags;
/* first_unacked_ts is timestamp when ngtcp2_acktr_entry is added
first time after the last outgoing ACK frame. */
ngtcp2_tstamp first_unacked_ts;
uint64_t ce;
} ack;
} ecn;
+
+ /* flags is bitwise OR of zero, or more of NGTCP2_ACKTR_FLAG_*. */
+ uint16_t flags;
} ngtcp2_acktr;
/*
ngtcp2_tstamp min_rtt_stamp;
ngtcp2_tstamp probe_rtt_done_stamp;
int probe_rtt_round_done;
- uint64_t prior_cwnd;
int idle_restart;
+ uint64_t prior_cwnd;
ngtcp2_tstamp extra_acked_interval_start;
uint64_t extra_acked_delivered;
/* Round counting */
uint64_t next_round_delivered;
- int round_start;
uint64_t round_count;
+ int round_start;
/* Full pipe */
uint64_t full_bw;
uint64_t undo_inflight_shortterm;
uint64_t undo_inflight_longterm;
- int loss_round_start;
uint64_t loss_round_delivered;
uint64_t rounds_since_bw_probe;
uint64_t max_bw;
ngtcp2_tstamp cycle_stamp;
ngtcp2_bbr_ack_phase ack_phase;
ngtcp2_duration bw_probe_wait;
- int bw_probe_samples;
size_t bw_probe_up_rounds;
uint64_t bw_probe_up_acks;
uint64_t inflight_longterm;
- int probe_rtt_expired;
ngtcp2_duration probe_rtt_min_delay;
ngtcp2_tstamp probe_rtt_min_stamp;
- int in_loss_recovery;
uint64_t round_count_at_recovery;
uint64_t max_inflight;
uint64_t bdp;
+ int loss_round_start;
+ int bw_probe_samples;
+ int probe_rtt_expired;
+ int in_loss_recovery;
} ngtcp2_cc_bbr;
void ngtcp2_cc_bbr_init(ngtcp2_cc_bbr *bbr, ngtcp2_log *log,
}
/*
- * conn_cut_crypto_frame splits (*pfrc)->fr.stream by removing
- * |removed_data| from (*pfrc)->fr.stream.data[0].
- * (*pfrc)->fr.stream.data[0] must contain |removed_data|, and
- * (*pfrc)->fr.stream.datacnt >= 1. New ngtcp2_frame_chain object
- * that contains |removed_data| is created, and pushed to
- * |crypto_strm| via ngtcp2_strm_streamfrq_push. Because
- * (*pfrc)->fr.stream.datacnt cannot be changed, if it is not 1, new
- * ngtcp2_frame_chain object is created to contain the data before
- * |removed_data|. Then *pfrc is deleted, and the newly created
- * object is assigned to *pfrc instead. If there are data following
- * the removed part of data, new ngtcp2_frame_chain object is created
- * for it, and (*pfrc)->next points to the object.
+ * conn_cut_crypto_frame splits frc->fr.stream by removing
+ * |removed_data| from frc->fr.stream.data[0]. frc->fr.stream.data[0]
+ * must contain |removed_data|, and frc->fr.stream.datacnt >= 1. New
+ * ngtcp2_frame_chain object that contains |removed_data| is created,
+ * and pushed to |crypto_strm| via ngtcp2_strm_streamfrq_push. If
+ * there are data following the removed part of data, new
+ * ngtcp2_frame_chain object is created for it, and frc->next points
+ * to the object.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
* NGTCP2_ERR_NOMEM
* Out of memory
*/
-static int conn_cut_crypto_frame(ngtcp2_conn *conn, ngtcp2_frame_chain **pfrc,
+static int conn_cut_crypto_frame(ngtcp2_conn *conn, ngtcp2_frame_chain *frc,
ngtcp2_strm *crypto_strm,
const ngtcp2_vec *removed_data) {
- ngtcp2_vec *data = (*pfrc)->fr.stream.data;
- size_t datacnt = (*pfrc)->fr.stream.datacnt;
+ ngtcp2_vec *data = frc->fr.stream.data;
+ size_t datacnt = frc->fr.stream.datacnt;
size_t ndatacnt;
- ngtcp2_frame_chain *left_frc, *right_frc = NULL, *removed_frc;
+ ngtcp2_frame_chain *right_frc = NULL, *removed_frc;
size_t offset;
int rv;
removed_frc->fr.stream.flags = 0;
removed_frc->fr.stream.fin = 0;
removed_frc->fr.stream.stream_id = 0;
- removed_frc->fr.stream.offset = (*pfrc)->fr.stream.offset + offset;
+ removed_frc->fr.stream.offset = frc->fr.stream.offset + offset;
removed_frc->fr.stream.datacnt = 1;
removed_frc->fr.stream.data[0] = (ngtcp2_vec){
.base = data->base + offset,
assert(1 == datacnt);
}
- /* We cannot change (*pfrc)->fr.stream.datacnt. If it changes,
- create new ngtcp2_frame_chain. */
- if ((*pfrc)->fr.stream.datacnt == 1) {
- (*pfrc)->fr.stream.data[0].len = offset;
- (*pfrc)->next = right_frc;
- return 0;
- }
-
- rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
- &left_frc, 1, &conn->frc_objalloc, conn->mem);
- if (rv != 0) {
- ngtcp2_frame_chain_objalloc_del(right_frc, &conn->frc_objalloc, conn->mem);
- return rv;
- }
-
- left_frc->fr.stream.type = NGTCP2_FRAME_CRYPTO;
- left_frc->fr.stream.flags = 0;
- left_frc->fr.stream.fin = 0;
- left_frc->fr.stream.stream_id = 0;
- left_frc->fr.stream.offset = (*pfrc)->fr.stream.offset;
- left_frc->fr.stream.datacnt = 1;
- left_frc->fr.stream.data[0] = (ngtcp2_vec){
- .base = data[0].base,
- .len = offset,
- };
- left_frc->next = right_frc;
-
- ngtcp2_frame_chain_objalloc_del(*pfrc, &conn->frc_objalloc, conn->mem);
- *pfrc = left_frc;
+ frc->fr.stream.datacnt = 1;
+ frc->fr.stream.data[0].len = offset;
+ frc->next = right_frc;
return 0;
}
datacnt = ngtcp2_pkt_remove_vec_partial(
&removed_data, data, datacnt, offsets, &conn->pcg, &server_name);
- rv = conn_cut_crypto_frame(conn, pfrc, crypto_strm, &removed_data);
+ rv = conn_cut_crypto_frame(conn, *pfrc, crypto_strm, &removed_data);
if (rv != 0) {
ngtcp2_frame_chain_objalloc_del(*pfrc, &conn->frc_objalloc, conn->mem);
return rv;
if (!(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) &&
pktns->rtb.num_retransmittable && pktns->rtb.probe_pkt_left) {
- num_reclaimed = ngtcp2_rtb_reclaim_on_pto(&pktns->rtb, conn, pktns, 1);
+ num_reclaimed = ngtcp2_rtb_reclaim_on_pto(
+ &pktns->rtb, conn, pktns,
+ !conn->server && type == NGTCP2_PKT_INITIAL ? 2 : 1);
if (num_reclaimed < 0) {
ngtcp2_frame_chain_list_objalloc_del(frq, &conn->frc_objalloc,
conn->mem);
num_acked =
ngtcp2_rtb_recv_ack(&pktns->rtb, fr, &conn->cstat, conn, pktns, pkt_ts, ts);
- if (num_acked < 0) {
+ if (num_acked <= 0) {
return (int)num_acked;
}
- if (num_acked == 0) {
- return 0;
- }
-
pktns->rtb.probe_pkt_left = 0;
if (cstat->pto_count &&
/* These parameters are treated specially. If server accepts early
data, it must not set values for these parameters that are
smaller than these remembered values. */
- conn->early.transport_params.initial_max_streams_bidi =
- params->initial_max_streams_bidi;
- conn->early.transport_params.initial_max_streams_uni =
- params->initial_max_streams_uni;
- conn->early.transport_params.initial_max_stream_data_bidi_local =
- params->initial_max_stream_data_bidi_local;
- conn->early.transport_params.initial_max_stream_data_bidi_remote =
- params->initial_max_stream_data_bidi_remote;
- conn->early.transport_params.initial_max_stream_data_uni =
- params->initial_max_stream_data_uni;
- conn->early.transport_params.initial_max_data = params->initial_max_data;
- conn->early.transport_params.active_connection_id_limit =
- params->active_connection_id_limit;
- conn->early.transport_params.max_datagram_frame_size =
- params->max_datagram_frame_size;
+ conn->early.transport_params = (ngtcp2_early_transport_params){
+ .initial_max_streams_bidi = params->initial_max_streams_bidi,
+ .initial_max_streams_uni = params->initial_max_streams_uni,
+ .initial_max_stream_data_bidi_local =
+ params->initial_max_stream_data_bidi_local,
+ .initial_max_stream_data_bidi_remote =
+ params->initial_max_stream_data_bidi_remote,
+ .initial_max_stream_data_uni = params->initial_max_stream_data_uni,
+ .initial_max_data = params->initial_max_data,
+ .active_connection_id_limit = params->active_connection_id_limit,
+ .max_datagram_frame_size = params->max_datagram_frame_size,
+ };
conn_sync_stream_id_limit(conn);
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 = (ngtcp2_vmsg){
+ .type = NGTCP2_VMSG_TYPE_STREAM,
+ .stream =
+ {
+ .strm = strm,
+ .data = datav,
+ .datacnt = datavcnt,
+ .pdatalen = pdatalen,
+ .flags = flags,
+ },
+ };
pvmsg = &vmsg;
}
return NGTCP2_ERR_INVALID_ARGUMENT;
}
- vmsg.type = NGTCP2_VMSG_TYPE_DATAGRAM;
- vmsg.datagram.dgram_id = dgram_id;
- vmsg.datagram.flags = flags;
- vmsg.datagram.data = datav;
- vmsg.datagram.datacnt = datavcnt;
- vmsg.datagram.paccepted = paccepted;
+ vmsg = (ngtcp2_vmsg){
+ .type = NGTCP2_VMSG_TYPE_DATAGRAM,
+ .datagram =
+ {
+ .data = datav,
+ .datacnt = datavcnt,
+ .dgram_id = dgram_id,
+ .paccepted = paccepted,
+ .flags = flags,
+ },
+ };
if (flags & NGTCP2_WRITE_DATAGRAM_FLAG_PADDING) {
wflags = NGTCP2_WRITE_PKT_FLAG_PADDING_IF_NOT_EMPTY;
typedef struct ngtcp2_path_challenge_entry {
ngtcp2_path_storage ps;
- uint8_t data[8];
+ uint8_t data[NGTCP2_PATH_CHALLENGE_DATALEN];
} ngtcp2_path_challenge_entry;
void ngtcp2_path_challenge_entry_init(ngtcp2_path_challenge_entry *pcent,
ngtcp2_tstamp last_max_data_ts;
struct {
- /* state is the state of ECN validation */
- ngtcp2_ecn_state state;
/* validation_start_ts is the timestamp when ECN validation is
started. It is UINT64_MAX if it has not started yet. */
ngtcp2_tstamp validation_start_ts;
/* dgram_sent is the number of UDP datagram sent during ECN
validation period. */
size_t dgram_sent;
+ /* state is the state of ECN validation */
+ ngtcp2_ecn_state state;
} ecn;
struct {
/* retry_aead_ctx is AEAD cipher context to verify Retry packet
integrity. It is used by client only. */
ngtcp2_crypto_aead_ctx retry_aead_ctx;
+ /* decryption_failure_count is the number of received packets that
+ fail authentication. */
+ uint64_t decryption_failure_count;
/* tls_error is TLS related error. */
int tls_error;
/* tls_alert is TLS alert generated by the local endpoint. */
uint8_t tls_alert;
- /* decryption_failure_count is the number of received packets that
- fail authentication. */
- uint64_t decryption_failure_count;
} crypto;
/* pkt contains the packet intermediate construction data to support
ngtcp2_pkt_hd hd;
ngtcp2_ppe ppe;
ngtcp2_frame_chain **pfrc;
+ ngtcp2_ssize hs_spktlen;
int pkt_empty;
int hd_logged;
+ int require_padding;
/* flags is bitwise OR of zero or more of
NGTCP2_RTB_ENTRY_FLAG_*. */
uint16_t rtb_entry_flags;
- ngtcp2_ssize hs_spktlen;
- int require_padding;
} pkt;
struct {
ngtcp2_log log;
ngtcp2_qlog qlog;
ngtcp2_rst rst;
- ngtcp2_cc_algo cc_algo;
union {
ngtcp2_cc cc;
ngtcp2_cc_reno reno;
uint32_t negotiated_version;
/* flags is bitwise OR of zero or more of NGTCP2_CONN_FLAG_*. */
uint32_t flags;
+ ngtcp2_cc_algo cc_algo;
int server;
};
typedef struct ngtcp2_vmsg_stream {
/* strm is a stream that data is sent to. */
ngtcp2_strm *strm;
- /* flags is bitwise OR of zero or more of
- NGTCP2_WRITE_STREAM_FLAG_*. */
- uint32_t flags;
/* data is the pointer to ngtcp2_vec array which contains the stream
data to send. */
const ngtcp2_vec *data;
/* pdatalen is the pointer to the variable which the number of bytes
written is assigned to if pdatalen is not NULL. */
ngtcp2_ssize *pdatalen;
+ /* flags is bitwise OR of zero or more of
+ NGTCP2_WRITE_STREAM_FLAG_*. */
+ uint32_t flags;
} ngtcp2_vmsg_stream;
typedef struct ngtcp2_vmsg_datagram {
size_t datacnt;
/* dgram_id is an opaque identifier chosen by an application. */
uint64_t dgram_id;
- /* flags is bitwise OR of zero or more of
- NGTCP2_WRITE_DATAGRAM_FLAG_*. */
- uint32_t flags;
/* paccepted is the pointer to the variable which, if it is not
NULL, is assigned nonzero if data is written to a packet. */
int *paccepted;
+ /* flags is bitwise OR of zero or more of
+ NGTCP2_WRITE_DATAGRAM_FLAG_*. */
+ uint32_t flags;
} ngtcp2_vmsg_datagram;
typedef struct ngtcp2_vmsg {
return NGTCP2_ERR_NOMEM;
}
- ngtcp2_frame_chain_init(*pfrc);
+ ngtcp2_frame_chain_init(*pfrc, NGTCP2_FRAME_CHAIN_FLAG_NONE);
return 0;
}
return NGTCP2_ERR_NOMEM;
}
- ngtcp2_frame_chain_init(*pfrc);
+ ngtcp2_frame_chain_init(*pfrc, NGTCP2_FRAME_CHAIN_FLAG_MALLOC);
return 0;
}
return 0;
}
-void ngtcp2_frame_chain_del(ngtcp2_frame_chain *frc, const ngtcp2_mem *mem) {
- ngtcp2_frame_chain_binder *binder;
-
- if (frc == NULL) {
- return;
- }
-
- binder = frc->binder;
- if (binder && --binder->refcount == 0) {
- ngtcp2_mem_free(mem, binder);
- }
-
- ngtcp2_mem_free(mem, frc);
-}
-
void ngtcp2_frame_chain_objalloc_del(ngtcp2_frame_chain *frc,
ngtcp2_objalloc *objalloc,
const ngtcp2_mem *mem) {
return;
}
- switch (frc->fr.hd.type) {
- case NGTCP2_FRAME_CRYPTO:
- case NGTCP2_FRAME_STREAM:
- if (frc->fr.stream.datacnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) {
- ngtcp2_frame_chain_del(frc, mem);
-
- return;
- }
-
- break;
- case NGTCP2_FRAME_NEW_TOKEN:
- if (frc->fr.new_token.tokenlen > NGTCP2_FRAME_CHAIN_NEW_TOKEN_THRES) {
- ngtcp2_frame_chain_del(frc, mem);
-
- return;
- }
-
- break;
- }
-
binder = frc->binder;
if (binder && --binder->refcount == 0) {
ngtcp2_mem_free(mem, binder);
}
- frc->binder = NULL;
+ if (frc->flags & NGTCP2_FRAME_CHAIN_FLAG_MALLOC) {
+ ngtcp2_mem_free(mem, frc);
+ return;
+ }
ngtcp2_objalloc_frame_chain_release(objalloc, frc);
}
-void ngtcp2_frame_chain_init(ngtcp2_frame_chain *frc) {
+void ngtcp2_frame_chain_init(ngtcp2_frame_chain *frc, uint32_t flags) {
frc->next = NULL;
frc->binder = NULL;
+ frc->flags = flags;
}
void ngtcp2_frame_chain_list_objalloc_del(ngtcp2_frame_chain *frc,
#define NGTCP2_FRAME_CHAIN_NEW_TOKEN_THRES \
(NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES * sizeof(ngtcp2_vec))
+/* NGTCP2_FRAME_CHAIN_FLAG_NONE indicates no flag is set. */
+#define NGTCP2_FRAME_CHAIN_FLAG_NONE 0x0
+/* NGTCP2_FRAME_CHAIN_FLAG_MALLOC indicates that ngtcp2_frame_chain is
+ allocated by ngtcp2_mem_malloc. */
+#define NGTCP2_FRAME_CHAIN_FLAG_MALLOC 0x1
+
typedef struct ngtcp2_frame_chain ngtcp2_frame_chain;
/*
struct {
ngtcp2_frame_chain *next;
ngtcp2_frame_chain_binder *binder;
+ uint32_t flags;
ngtcp2_frame fr;
uint8_t buf[sizeof(ngtcp2_vec) * NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES];
};
* words, |datacnt| <= NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES,
* ngtcp2_frame_chain_objalloc_new is called internally. Otherwise,
* ngtcp2_frame_chain_extralen_new is used and objalloc is not used.
- * Therefore, it is important to call ngtcp2_frame_chain_objalloc_del
- * without changing datacnt field.
*/
int ngtcp2_frame_chain_stream_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc,
size_t datacnt,
const ngtcp2_mem *mem);
/*
- * ngtcp2_frame_chain_del deallocates |frc|. It also deallocates the
- * memory pointed by |frc|.
- */
-void ngtcp2_frame_chain_del(ngtcp2_frame_chain *frc, const ngtcp2_mem *mem);
-
-/*
- * ngtcp2_frame_chain_objalloc_del adds |frc| to |objalloc| for reuse.
- * It might just delete |frc| depending on the frame type and the size
- * of |frc|.
+ * ngtcp2_frame_chain_objalloc_del adds |frc| to |objalloc| for reuse
+ * if NGTCP2_FRAME_CHAIN_FLAG_MALLOC is not set in |frc|->flags.
+ * Otherwise, it deletes |frc|.
*/
void ngtcp2_frame_chain_objalloc_del(ngtcp2_frame_chain *frc,
ngtcp2_objalloc *objalloc,
const ngtcp2_mem *mem);
/*
- * ngtcp2_frame_chain_init initializes |frc|.
+ * ngtcp2_frame_chain_init initializes |frc|. |flags| is bitwise-OR
+ * of zero or more of NGTCP2_FRAME_CHAIN_FLAG_*.
*/
-void ngtcp2_frame_chain_init(ngtcp2_frame_chain *frc);
+void ngtcp2_frame_chain_init(ngtcp2_frame_chain *frc, uint32_t flags);
/*
* ngtcp2_frame_chain_list_objalloc_del adds all ngtcp2_frame_chain
aligned_keylen = (keylen + 0x7u) & ~0x7u;
+ assert(aligned_keylen <= UINT16_MAX);
+
ngtcp2_objalloc_init(&ksl->blkalloc,
(ksl_blklen(aligned_keylen) + 0xfu) & ~(uintptr_t)0xfu,
mem);
- ksl->head = NULL;
+ ksl->root = NULL;
ksl->front = ksl->back = NULL;
ksl->compar = compar;
ksl->search = search;
}
blk->keys = (uint8_t *)blk + sizeof(*blk);
+ blk->aligned_keylen = (uint16_t)ksl->aligned_keylen;
return blk;
}
ngtcp2_objalloc_ksl_blk_release(&ksl->blkalloc, blk);
}
-static int ksl_head_init(ngtcp2_ksl *ksl) {
- ngtcp2_ksl_blk *head = ksl_blk_objalloc_new(ksl);
+static int ksl_root_init(ngtcp2_ksl *ksl) {
+ ngtcp2_ksl_blk *root = ksl_blk_objalloc_new(ksl);
- if (!head) {
+ if (!root) {
return NGTCP2_ERR_NOMEM;
}
- head->next = head->prev = NULL;
- head->n = 0;
- head->leaf = 1;
+ root->next = root->prev = NULL;
+ root->n = 0;
+ root->leaf = 1;
- ksl->head = head;
- ksl->front = ksl->back = head;
+ ksl->root = root;
+ ksl->front = ksl->back = root;
return 0;
}
#endif /* defined(NOMEMPOOL) */
void ngtcp2_ksl_free(ngtcp2_ksl *ksl) {
- if (!ksl || !ksl->head) {
+ if (!ksl || !ksl->root) {
return;
}
#ifdef NOMEMPOOL
- ksl_free_blk(ksl, ksl->head);
+ ksl_free_blk(ksl, ksl->root);
#endif /* defined(NOMEMPOOL) */
ngtcp2_objalloc_free(&ksl->blkalloc);
memmove(blk->nodes + (i + 2), blk->nodes + (i + 1),
(blk->n - (i + 1)) * sizeof(ngtcp2_ksl_node));
- memmove(blk->keys + (i + 2) * ksl->aligned_keylen,
- blk->keys + (i + 1) * ksl->aligned_keylen,
- (blk->n - (i + 1)) * ksl->aligned_keylen);
+ memmove(blk->keys + (i + 1) * ksl->aligned_keylen,
+ blk->keys + i * ksl->aligned_keylen,
+ (blk->n - i) * ksl->aligned_keylen);
blk->nodes[i + 1].blk = rblk;
++blk->n;
- ksl_set_nth_key(ksl, blk, i + 1, ngtcp2_ksl_nth_key(ksl, rblk, rblk->n - 1));
- ksl_set_nth_key(ksl, blk, i, ngtcp2_ksl_nth_key(ksl, lblk, lblk->n - 1));
+ ksl_set_nth_key(ksl, blk, i, ngtcp2_ksl_blk_nth_key(lblk, lblk->n - 1));
return 0;
}
/*
- * ksl_split_head splits a head (root) block. It increases the height
- * of skip list by 1.
+ * ksl_split_root splits a root block. It increases the height of
+ * skip list by 1.
*
* It returns 0 if it succeeds, or one of the following negative error
* codes:
* NGTCP2_ERR_NOMEM
* Out of memory.
*/
-static int ksl_split_head(ngtcp2_ksl *ksl) {
- ngtcp2_ksl_blk *rblk = NULL, *lblk, *nhead = NULL;
+static int ksl_split_root(ngtcp2_ksl *ksl) {
+ ngtcp2_ksl_blk *rblk = NULL, *lblk, *nroot = NULL;
- rblk = ksl_split_blk(ksl, ksl->head);
+ rblk = ksl_split_blk(ksl, ksl->root);
if (rblk == NULL) {
return NGTCP2_ERR_NOMEM;
}
- lblk = ksl->head;
+ lblk = ksl->root;
- nhead = ksl_blk_objalloc_new(ksl);
+ nroot = ksl_blk_objalloc_new(ksl);
- if (nhead == NULL) {
+ if (nroot == NULL) {
ksl_blk_objalloc_del(ksl, rblk);
return NGTCP2_ERR_NOMEM;
}
- nhead->next = nhead->prev = NULL;
- nhead->n = 2;
- nhead->leaf = 0;
+ nroot->next = nroot->prev = NULL;
+ nroot->n = 2;
+ nroot->leaf = 0;
- ksl_set_nth_key(ksl, nhead, 0, ngtcp2_ksl_nth_key(ksl, lblk, lblk->n - 1));
- nhead->nodes[0].blk = lblk;
+ ksl_set_nth_key(ksl, nroot, 0, ngtcp2_ksl_blk_nth_key(lblk, lblk->n - 1));
+ nroot->nodes[0].blk = lblk;
- ksl_set_nth_key(ksl, nhead, 1, ngtcp2_ksl_nth_key(ksl, rblk, rblk->n - 1));
- nhead->nodes[1].blk = rblk;
+ ksl_set_nth_key(ksl, nroot, 1, ngtcp2_ksl_blk_nth_key(rblk, rblk->n - 1));
+ nroot->nodes[1].blk = rblk;
- ksl->head = nhead;
+ ksl->root = nroot;
return 0;
}
size_t i;
int rv;
- if (!ksl->head) {
- rv = ksl_head_init(ksl);
+ if (!ksl->root) {
+ rv = ksl_root_init(ksl);
if (rv != 0) {
return rv;
}
}
- if (ksl->head->n == NGTCP2_KSL_MAX_NBLK) {
- rv = ksl_split_head(ksl);
+ if (ksl->root->n == NGTCP2_KSL_MAX_NBLK) {
+ rv = ksl_split_root(ksl);
if (rv != 0) {
return rv;
}
}
- blk = ksl->head;
+ blk = ksl->root;
for (;;) {
i = ksl->search(ksl, blk, key);
if (blk->leaf) {
- if (i < blk->n && !ksl->compar(key, ngtcp2_ksl_nth_key(ksl, blk, i))) {
+ if (i < blk->n && !ksl->compar(key, ngtcp2_ksl_blk_nth_key(blk, i))) {
if (it) {
*it = ngtcp2_ksl_end(ksl);
}
++ksl->n;
if (it) {
- ngtcp2_ksl_it_init(it, ksl, blk, i);
+ ngtcp2_ksl_it_init(it, blk, i);
}
return 0;
++ksl->n;
if (it) {
- ngtcp2_ksl_it_init(it, ksl, blk, blk->n - 1);
+ ngtcp2_ksl_it_init(it, blk, blk->n - 1);
}
return 0;
return rv;
}
- if (ksl->compar(ngtcp2_ksl_nth_key(ksl, blk, i), key)) {
+ if (ksl->compar(ngtcp2_ksl_blk_nth_key(blk, i), key)) {
node = &blk->nodes[i + 1];
-
- if (ksl->compar(ngtcp2_ksl_nth_key(ksl, blk, i + 1), key)) {
- ksl_set_nth_key(ksl, blk, i + 1, key);
- }
}
}
* ksl_merge_node merges 2 nodes which are the nodes at the index of
* |i| and |i + 1|.
*
- * If |blk| is the head (root) block and it contains just 2 nodes
- * before merging nodes, the merged block becomes head block, which
- * decreases the height of |ksl| by 1.
+ * If |blk| is the root block and it contains just 2 nodes before
+ * merging nodes, the merged block becomes root block, which decreases
+ * the height of |ksl| by 1.
*
* This function returns the pointer to the merged block.
*/
lblk = lnode->blk;
rblk = blk->nodes[i + 1].blk;
- assert(lblk->n + rblk->n < NGTCP2_KSL_MAX_NBLK);
+ assert(lblk->n + rblk->n <= NGTCP2_KSL_MAX_NBLK);
memcpy(lblk->nodes + lblk->n, rblk->nodes, rblk->n * sizeof(ngtcp2_ksl_node));
ksl_blk_objalloc_del(ksl, rblk);
- if (ksl->head == blk && blk->n == 2) {
- ksl_blk_objalloc_del(ksl, ksl->head);
- ksl->head = lblk;
+ if (ksl->root == blk && blk->n == 2) {
+ ksl_blk_objalloc_del(ksl, ksl->root);
+ ksl->root = lblk;
} else {
ksl_remove_node(ksl, blk, i + 1);
- ksl_set_nth_key(ksl, blk, i, ngtcp2_ksl_nth_key(ksl, lblk, lblk->n - 1));
+ ksl_set_nth_key(ksl, blk, i, ngtcp2_ksl_blk_nth_key(lblk, lblk->n - 1));
}
return lblk;
lblk->n += (uint32_t)n;
rblk->n -= (uint32_t)n;
- ksl_set_nth_key(ksl, blk, i - 1, ngtcp2_ksl_nth_key(ksl, lblk, lblk->n - 1));
+ ksl_set_nth_key(ksl, blk, i - 1, ngtcp2_ksl_blk_nth_key(lblk, lblk->n - 1));
memmove(rblk->nodes, rblk->nodes + n, rblk->n * sizeof(ngtcp2_ksl_node));
memcpy(rblk->keys, lblk->keys + lblk->n * ksl->aligned_keylen,
n * ksl->aligned_keylen);
- ksl_set_nth_key(ksl, blk, i, ngtcp2_ksl_nth_key(ksl, lblk, lblk->n - 1));
+ ksl_set_nth_key(ksl, blk, i, ngtcp2_ksl_blk_nth_key(lblk, lblk->n - 1));
}
/*
const ngtcp2_ksl_key *key) {
ngtcp2_ksl_blk *blk = hint->blk;
- assert(ksl->head);
+ assert(ksl->root);
- if (blk->n <= NGTCP2_KSL_MIN_NBLK) {
+ if (blk != ksl->root && blk->n == NGTCP2_KSL_MIN_NBLK) {
return ngtcp2_ksl_remove(ksl, it, key);
}
if (it) {
if (hint->i == blk->n && blk->next) {
- ngtcp2_ksl_it_init(it, ksl, blk->next, 0);
+ ngtcp2_ksl_it_init(it, blk->next, 0);
} else {
- ngtcp2_ksl_it_init(it, ksl, blk, hint->i);
+ ngtcp2_ksl_it_init(it, blk, hint->i);
}
}
int ngtcp2_ksl_remove(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it,
const ngtcp2_ksl_key *key) {
- ngtcp2_ksl_blk *blk = ksl->head;
+ ngtcp2_ksl_blk *blk = ksl->root;
ngtcp2_ksl_node *node;
size_t i;
}
if (blk->leaf) {
- if (ksl->compar(key, ngtcp2_ksl_nth_key(ksl, blk, i))) {
+ if (ksl->compar(key, ngtcp2_ksl_blk_nth_key(blk, i))) {
if (it) {
*it = ngtcp2_ksl_end(ksl);
}
if (it) {
if (blk->n == i && blk->next) {
- ngtcp2_ksl_it_init(it, ksl, blk->next, 0);
+ ngtcp2_ksl_it_init(it, blk->next, 0);
} else {
- ngtcp2_ksl_it_init(it, ksl, blk, i);
+ ngtcp2_ksl_it_init(it, blk, i);
}
}
ngtcp2_ksl_it ngtcp2_ksl_lower_bound_search(const ngtcp2_ksl *ksl,
const ngtcp2_ksl_key *key,
ngtcp2_ksl_search search) {
- ngtcp2_ksl_blk *blk = ksl->head;
+ ngtcp2_ksl_blk *blk = ksl->root;
ngtcp2_ksl_it it;
size_t i;
if (!blk) {
- ngtcp2_ksl_it_init(&it, ksl, &null_blk, 0);
+ ngtcp2_ksl_it_init(&it, &null_blk, 0);
return it;
}
i = 0;
}
- ngtcp2_ksl_it_init(&it, ksl, blk, i);
+ ngtcp2_ksl_it_init(&it, blk, i);
return it;
}
i = blk->n;
}
- ngtcp2_ksl_it_init(&it, ksl, blk, i);
+ ngtcp2_ksl_it_init(&it, blk, i);
return it;
}
void ngtcp2_ksl_update_key(ngtcp2_ksl *ksl, const ngtcp2_ksl_key *old_key,
const ngtcp2_ksl_key *new_key) {
- ngtcp2_ksl_blk *blk = ksl->head;
+ ngtcp2_ksl_blk *blk = ksl->root;
ngtcp2_ksl_node *node;
const ngtcp2_ksl_key *node_key;
size_t i;
- assert(ksl->head);
+ assert(ksl->root);
for (;;) {
i = ksl->search(ksl, blk, old_key);
assert(i < blk->n);
node = &blk->nodes[i];
- node_key = ngtcp2_ksl_nth_key(ksl, blk, i);
+ node_key = ngtcp2_ksl_blk_nth_key(blk, i);
if (blk->leaf) {
assert(key_equal(ksl->compar, node_key, old_key));
size_t ngtcp2_ksl_len(const ngtcp2_ksl *ksl) { return ksl->n; }
void ngtcp2_ksl_clear(ngtcp2_ksl *ksl) {
- if (!ksl->head) {
+ if (!ksl->root) {
return;
}
#ifdef NOMEMPOOL
- ksl_free_blk(ksl, ksl->head);
+ ksl_free_blk(ksl, ksl->root);
#endif /* defined(NOMEMPOOL) */
- ksl->front = ksl->back = ksl->head = NULL;
+ ksl->front = ksl->back = ksl->root = NULL;
ksl->n = 0;
ngtcp2_objalloc_clear(&ksl->blkalloc);
if (blk->leaf) {
for (i = 0; i < blk->n; ++i) {
- fprintf(stderr, " %" PRId64, *(int64_t *)ngtcp2_ksl_nth_key(ksl, blk, i));
+ fprintf(stderr, " %" PRId64, *(int64_t *)ngtcp2_ksl_blk_nth_key(blk, i));
}
fprintf(stderr, "\n");
}
void ngtcp2_ksl_print(const ngtcp2_ksl *ksl) {
- if (!ksl->head) {
+ if (!ksl->root) {
return;
}
- ksl_print(ksl, ksl->head, 0);
+ ksl_print(ksl, ksl->root, 0);
}
#endif /* !defined(WIN32) */
ngtcp2_ksl_it ngtcp2_ksl_begin(const ngtcp2_ksl *ksl) {
ngtcp2_ksl_it it;
- if (ksl->head) {
- ngtcp2_ksl_it_init(&it, ksl, ksl->front, 0);
+ if (ksl->root) {
+ ngtcp2_ksl_it_init(&it, ksl->front, 0);
} else {
- ngtcp2_ksl_it_init(&it, ksl, &null_blk, 0);
+ ngtcp2_ksl_it_init(&it, &null_blk, 0);
}
return it;
ngtcp2_ksl_it ngtcp2_ksl_end(const ngtcp2_ksl *ksl) {
ngtcp2_ksl_it it;
- if (ksl->head) {
- ngtcp2_ksl_it_init(&it, ksl, ksl->back, ksl->back->n);
+ if (ksl->root) {
+ ngtcp2_ksl_it_init(&it, ksl->back, ksl->back->n);
} else {
- ngtcp2_ksl_it_init(&it, ksl, &null_blk, 0);
+ ngtcp2_ksl_it_init(&it, &null_blk, 0);
}
return it;
}
-void ngtcp2_ksl_it_init(ngtcp2_ksl_it *it, const ngtcp2_ksl *ksl,
- ngtcp2_ksl_blk *blk, size_t i) {
- it->ksl = ksl;
+void ngtcp2_ksl_it_init(ngtcp2_ksl_it *it, ngtcp2_ksl_blk *blk, size_t i) {
it->blk = blk;
it->i = i;
}
#define NGTCP2_KSL_DEGR 16
/* NGTCP2_KSL_MAX_NBLK is the maximum number of nodes which a single
block can contain. */
-#define NGTCP2_KSL_MAX_NBLK (2 * NGTCP2_KSL_DEGR - 1)
+#define NGTCP2_KSL_MAX_NBLK (2 * NGTCP2_KSL_DEGR)
/* NGTCP2_KSL_MIN_NBLK is the minimum number of nodes which a single
block other than root must contain. */
-#define NGTCP2_KSL_MIN_NBLK (NGTCP2_KSL_DEGR - 1)
+#define NGTCP2_KSL_MIN_NBLK NGTCP2_KSL_DEGR
/*
* ngtcp2_ksl_key represents key in ngtcp2_ksl.
/* prev points to the previous block if leaf field is
nonzero. */
ngtcp2_ksl_blk *prev;
- /* n is the number of nodes this object contains in nodes. */
- uint32_t n;
- /* leaf is nonzero if this block contains leaf nodes. */
- uint32_t leaf;
ngtcp2_ksl_node nodes[NGTCP2_KSL_MAX_NBLK];
/* keys is a pointer to the buffer to include
NGTCP2_KSL_MAX_NBLK keys. Because the length of key is
unknown until ngtcp2_ksl_init is called, the actual buffer
- will be allocated after this field. */
+ will be allocated after this object. */
uint8_t *keys;
+ /* n is the number of nodes this object contains in nodes. */
+ uint32_t n;
+ /* aligned_keylen is the length of the single key including
+ alignment. */
+ uint16_t aligned_keylen;
+ /* leaf is nonzero if this block contains leaf nodes. */
+ uint8_t leaf;
};
ngtcp2_opl_entry oplent;
* ngtcp2_ksl_it is a bidirectional iterator to iterate nodes.
*/
struct ngtcp2_ksl_it {
- const ngtcp2_ksl *ksl;
ngtcp2_ksl_blk *blk;
size_t i;
};
*/
struct ngtcp2_ksl {
ngtcp2_objalloc blkalloc;
- /* head points to the root block. */
- ngtcp2_ksl_blk *head;
+ /* root points to the root block. */
+ ngtcp2_ksl_blk *root;
/* front points to the first leaf block. */
ngtcp2_ksl_blk *front;
/* back points to the last leaf block. */
void ngtcp2_ksl_clear(ngtcp2_ksl *ksl);
/*
- * ngtcp2_ksl_nth_key returns the |n|th key under |blk|.
+ * ngtcp2_ksl_blk_nth_key returns the |n|th key under |blk|.
*/
static inline const ngtcp2_ksl_key *
-ngtcp2_ksl_nth_key(const ngtcp2_ksl *ksl, const ngtcp2_ksl_blk *blk, size_t n) {
- return blk->keys + n * ksl->aligned_keylen;
+ngtcp2_ksl_blk_nth_key(const ngtcp2_ksl_blk *blk, size_t n) {
+ return blk->keys + n * blk->aligned_keylen;
}
#ifndef WIN32
/*
* ngtcp2_ksl_it_init initializes |it|.
*/
-void ngtcp2_ksl_it_init(ngtcp2_ksl_it *it, const ngtcp2_ksl *ksl,
- ngtcp2_ksl_blk *blk, size_t i);
+void ngtcp2_ksl_it_init(ngtcp2_ksl_it *it, ngtcp2_ksl_blk *blk, size_t i);
/*
* ngtcp2_ksl_it_get returns the data associated to the node which
* returns nonzero.
*/
static inline const ngtcp2_ksl_key *ngtcp2_ksl_it_key(const ngtcp2_ksl_it *it) {
- return ngtcp2_ksl_nth_key(it->ksl, it->blk, it->i);
+ return ngtcp2_ksl_blk_nth_key(it->blk, it->i);
}
/*
*/
#define ngtcp2_arraylen(A) (sizeof(A) / sizeof(A[0]))
+/*
+ * ngtcp2_strlen_lit returns the length of string literal |S|. This
+ * macro assumes |S| is NULL-terminated string literal. It must not
+ * be used with pointers.
+ */
+#define ngtcp2_strlen_lit(S) (sizeof(S) - 1)
+
#define ngtcp2_max_def(SUFFIX, T) \
static inline T ngtcp2_max_##SUFFIX(T a, T b) { return a < b ? b : a; }
case NGTCP2_PROTO_VER_V1:
default:
nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_V1;
- noncelen = sizeof(NGTCP2_RETRY_NONCE_V1) - 1;
+ noncelen = ngtcp2_strlen_lit(NGTCP2_RETRY_NONCE_V1);
break;
case NGTCP2_PROTO_VER_V2:
nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_V2;
- noncelen = sizeof(NGTCP2_RETRY_NONCE_V2) - 1;
+ noncelen = ngtcp2_strlen_lit(NGTCP2_RETRY_NONCE_V2);
break;
}
case NGTCP2_PROTO_VER_V1:
default:
nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_V1;
- noncelen = sizeof(NGTCP2_RETRY_NONCE_V1) - 1;
+ noncelen = ngtcp2_strlen_lit(NGTCP2_RETRY_NONCE_V1);
break;
case NGTCP2_PROTO_VER_V2:
nonce = (const uint8_t *)NGTCP2_RETRY_NONCE_V2;
- noncelen = sizeof(NGTCP2_RETRY_NONCE_V2) - 1;
+ noncelen = ngtcp2_strlen_lit(NGTCP2_RETRY_NONCE_V2);
break;
}
/* flags is zero or more of NGTCP2_PV_ENTRY_FLAG_*. */
uint8_t flags;
/* data is a byte string included in PATH_CHALLENGE. */
- uint8_t data[8];
+ uint8_t data[NGTCP2_PATH_CHALLENGE_DATALEN];
} ngtcp2_pv_entry;
void ngtcp2_pv_entry_init(ngtcp2_pv_entry *pvent, const uint8_t *data,
qlog->user_data = user_data;
}
-#define write_verbatim(DEST, S) ngtcp2_cpymem((DEST), (S), sizeof(S) - 1)
+#define write_verbatim(DEST, S) ngtcp2_cpymem((DEST), (S), ngtcp2_strlen_lit(S))
static uint8_t *write_string_impl(uint8_t *p, const uint8_t *data,
size_t datalen) {
}
#define write_string(DEST, S) \
- write_string_impl((DEST), (const uint8_t *)(S), sizeof(S) - 1)
+ write_string_impl((DEST), (const uint8_t *)(S), ngtcp2_strlen_lit(S))
static uint8_t *write_hex(uint8_t *p, const uint8_t *data, size_t datalen) {
*p++ = '"';
static uint8_t *write_bool(uint8_t *p, int b) {
if (b) {
- return ngtcp2_cpymem(p, "true", sizeof("true") - 1);
+ return ngtcp2_cpymem(p, "true", ngtcp2_strlen_lit("true"));
}
- return ngtcp2_cpymem(p, "false", sizeof("false") - 1);
+ return ngtcp2_cpymem(p, "false", ngtcp2_strlen_lit("false"));
}
static uint8_t *write_pair_impl(uint8_t *p, const uint8_t *name, size_t namelen,
}
#define write_pair(DEST, NAME, VALUE) \
- write_pair_impl((DEST), (const uint8_t *)(NAME), sizeof(NAME) - 1, (VALUE))
+ write_pair_impl((DEST), (const uint8_t *)(NAME), ngtcp2_strlen_lit(NAME), \
+ (VALUE))
static uint8_t *write_pair_hex_impl(uint8_t *p, const uint8_t *name,
size_t namelen, const uint8_t *value,
}
#define write_pair_hex(DEST, NAME, VALUE, VALUELEN) \
- write_pair_hex_impl((DEST), (const uint8_t *)(NAME), sizeof(NAME) - 1, \
- (VALUE), (VALUELEN))
+ write_pair_hex_impl((DEST), (const uint8_t *)(NAME), \
+ ngtcp2_strlen_lit(NAME), (VALUE), (VALUELEN))
static uint8_t *write_pair_number_impl(uint8_t *p, const uint8_t *name,
size_t namelen, uint64_t value) {
}
#define write_pair_number(DEST, NAME, VALUE) \
- write_pair_number_impl((DEST), (const uint8_t *)(NAME), sizeof(NAME) - 1, \
- (VALUE))
+ write_pair_number_impl((DEST), (const uint8_t *)(NAME), \
+ ngtcp2_strlen_lit(NAME), (VALUE))
static uint8_t *write_pair_duration_impl(uint8_t *p, const uint8_t *name,
size_t namelen,
}
#define write_pair_duration(DEST, NAME, VALUE) \
- write_pair_duration_impl((DEST), (const uint8_t *)(NAME), sizeof(NAME) - 1, \
- (VALUE))
+ write_pair_duration_impl((DEST), (const uint8_t *)(NAME), \
+ ngtcp2_strlen_lit(NAME), (VALUE))
static uint8_t *write_pair_tstamp_impl(uint8_t *p, const uint8_t *name,
size_t namelen, ngtcp2_tstamp ts) {
}
#define write_pair_tstamp(DEST, NAME, VALUE) \
- write_pair_tstamp_impl((DEST), (const uint8_t *)(NAME), sizeof(NAME) - 1, \
- (VALUE))
+ write_pair_tstamp_impl((DEST), (const uint8_t *)(NAME), \
+ ngtcp2_strlen_lit(NAME), (VALUE))
static uint8_t *write_pair_bool_impl(uint8_t *p, const uint8_t *name,
size_t namelen, int b) {
}
#define write_pair_bool(DEST, NAME, VALUE) \
- write_pair_bool_impl((DEST), (const uint8_t *)(NAME), sizeof(NAME) - 1, \
- (VALUE))
+ write_pair_bool_impl((DEST), (const uint8_t *)(NAME), \
+ ngtcp2_strlen_lit(NAME), (VALUE))
static uint8_t *write_pair_cid_impl(uint8_t *p, const uint8_t *name,
size_t namelen, const ngtcp2_cid *cid) {
}
#define write_pair_cid(DEST, NAME, VALUE) \
- write_pair_cid_impl((DEST), (const uint8_t *)(NAME), sizeof(NAME) - 1, \
- (VALUE))
+ write_pair_cid_impl((DEST), (const uint8_t *)(NAME), \
+ ngtcp2_strlen_lit(NAME), (VALUE))
-#define ngtcp2_make_vec_lit(S) {(uint8_t *)(S), sizeof((S)) - 1}
+#define ngtcp2_make_vec_lit(S) {(uint8_t *)(S), ngtcp2_strlen_lit((S))}
static uint8_t *write_common_fields(uint8_t *p, const ngtcp2_cid *odcid) {
p = write_verbatim(
buf.last = write_verbatim(buf.last, ",\"supported_versions\":[");
if (nsv) {
- if (ngtcp2_buf_left(&buf) <
- (sizeof("\"xxxxxxxx\",") - 1) * nsv - 1 + sizeof("]}}\n") - 1) {
+ if (ngtcp2_buf_left(&buf) < ngtcp2_strlen_lit("\"xxxxxxxx\",") * nsv - 1 +
+ ngtcp2_strlen_lit("]}}\n")) {
return;
}
/* NGTCP2_DEFAULT_GLITCH_RATELIM_BURST is the maximum number of tokens
in glitch rate limiter. It is also the initial value. */
-#define NGTCP2_DEFAULT_GLITCH_RATELIM_BURST 4000
+#define NGTCP2_DEFAULT_GLITCH_RATELIM_BURST 10000
/* NGTCP2_DEFAULT_GLITCH_RATELIM_RATE is the rate of tokens generated
per second for glitch rate limiter. */
-#define NGTCP2_DEFAULT_GLITCH_RATELIM_RATE 132
+#define NGTCP2_DEFAULT_GLITCH_RATELIM_RATE 330
/*
* ngtcp2_settings_convert_to_latest converts |src| of version
if (rv != 0) {
return rv;
}
- } else if (ngtcp2_ksl_len(strm->tx.streamfrq) >= 1000) {
+ } else if (ngtcp2_ksl_len(strm->tx.streamfrq) >= 8000) {
return NGTCP2_ERR_INTERNAL;
}
int ngtcp2_strm_streamfrq_pop(ngtcp2_strm *strm, ngtcp2_frame_chain **pfrc,
size_t left) {
ngtcp2_stream *fr, *nfr;
- ngtcp2_frame_chain *frc, *nfrc, *sfrc;
+ ngtcp2_frame_chain *frc, *nfrc;
int rv;
size_t nmerged;
uint64_t datalen;
- ngtcp2_vec a[NGTCP2_MAX_STREAM_DATACNT];
- ngtcp2_vec b[NGTCP2_MAX_STREAM_DATACNT];
- size_t acnt, bcnt;
+ ngtcp2_vec data[NGTCP2_MAX_STREAM_DATACNT];
+ size_t datacnt;
uint64_t unacked_offset;
if (strm->tx.streamfrq == NULL || ngtcp2_ksl_len(strm->tx.streamfrq) == 0) {
}
if (datalen > left) {
- ngtcp2_vec_copy(a, fr->data, fr->datacnt);
- acnt = fr->datacnt;
-
- bcnt = 0;
- ngtcp2_vec_split(b, &bcnt, a, &acnt, left, NGTCP2_MAX_STREAM_DATACNT);
+ datacnt = 0;
+ ngtcp2_vec_split(data, &datacnt, fr->data, &fr->datacnt, left,
+ NGTCP2_MAX_STREAM_DATACNT);
- assert(acnt > 0);
- assert(bcnt > 0);
+ assert(fr->datacnt > 0);
+ assert(datacnt > 0);
rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
- &nfrc, bcnt, strm->frc_objalloc, strm->mem);
+ &nfrc, datacnt, strm->frc_objalloc, strm->mem);
if (rv != 0) {
assert(ngtcp2_err_is_fatal(rv));
ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
nfr->fin = fr->fin;
nfr->stream_id = fr->stream_id;
nfr->offset = fr->offset + left;
- nfr->datacnt = bcnt;
- ngtcp2_vec_copy(nfr->data, b, bcnt);
+ nfr->datacnt = datacnt;
+ ngtcp2_vec_copy(nfr->data, data, datacnt);
rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &nfr->offset, nfrc);
if (rv != 0) {
return rv;
}
- rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
- &nfrc, acnt, strm->frc_objalloc, strm->mem);
- if (rv != 0) {
- assert(ngtcp2_err_is_fatal(rv));
- ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
- return rv;
- }
-
- nfr = &nfrc->fr.stream;
- nfr->type = fr->type;
- nfr->flags = fr->flags;
- nfr->fin = 0;
- nfr->stream_id = fr->stream_id;
- nfr->offset = fr->offset;
- nfr->datacnt = acnt;
- ngtcp2_vec_copy(nfr->data, a, acnt);
-
- ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
+ fr->fin = 0;
- *pfrc = nfrc;
+ *pfrc = frc;
return 0;
}
left -= (size_t)datalen;
- ngtcp2_vec_copy(a, fr->data, fr->datacnt);
- acnt = fr->datacnt;
+ ngtcp2_vec_copy(data, fr->data, fr->datacnt);
+ datacnt = fr->datacnt;
for (; left && ngtcp2_ksl_len(strm->tx.streamfrq);) {
unacked_offset = ngtcp2_strm_streamfrq_unacked_offset(strm);
break;
}
- bcnt = nfr->datacnt;
-
- nmerged = ngtcp2_vec_merge(a, &acnt, nfr->data, &bcnt, left,
+ nmerged = ngtcp2_vec_merge(data, &datacnt, nfr->data, &nfr->datacnt, left,
NGTCP2_MAX_STREAM_DATACNT);
if (nmerged == 0) {
rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &nfr->offset, nfrc);
datalen += nmerged;
left -= nmerged;
- if (bcnt == 0) {
+ if (nfr->datacnt == 0) {
fr->fin = nfr->fin;
ngtcp2_frame_chain_objalloc_del(nfrc, strm->frc_objalloc, strm->mem);
continue;
}
- if (nfr->datacnt <= NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES ||
- bcnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) {
- nfr->offset += nmerged;
- nfr->datacnt = bcnt;
-
- rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &nfr->offset, nfrc);
- if (rv != 0) {
- ngtcp2_frame_chain_objalloc_del(nfrc, strm->frc_objalloc, strm->mem);
- ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
- return rv;
- }
- } else {
- rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
- &sfrc, bcnt, strm->frc_objalloc, strm->mem);
- if (rv != 0) {
- ngtcp2_frame_chain_objalloc_del(nfrc, strm->frc_objalloc, strm->mem);
- ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
- return rv;
- }
-
- sfrc->fr.stream = nfrc->fr.stream;
- sfrc->fr.stream.offset += nmerged;
- sfrc->fr.stream.datacnt = bcnt;
- ngtcp2_vec_copy(sfrc->fr.stream.data, nfrc->fr.stream.data, bcnt);
+ nfr->offset += nmerged;
+ rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &nfr->offset, nfrc);
+ if (rv != 0) {
ngtcp2_frame_chain_objalloc_del(nfrc, strm->frc_objalloc, strm->mem);
-
- rv = ngtcp2_ksl_insert(strm->tx.streamfrq, NULL, &sfrc->fr.stream.offset,
- sfrc);
- if (rv != 0) {
- ngtcp2_frame_chain_objalloc_del(sfrc, strm->frc_objalloc, strm->mem);
- ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
- return rv;
- }
+ ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
+ return rv;
}
break;
}
- if (acnt == fr->datacnt) {
- if (acnt > 0) {
- fr->data[acnt - 1] = a[acnt - 1];
+ if (datacnt == fr->datacnt) {
+ if (datacnt > 0) {
+ fr->data[datacnt - 1] = data[datacnt - 1];
}
*pfrc = frc;
return 0;
}
- assert(acnt > fr->datacnt);
+ assert(datacnt > fr->datacnt);
rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
- &nfrc, acnt, strm->frc_objalloc, strm->mem);
+ &nfrc, datacnt, strm->frc_objalloc, strm->mem);
if (rv != 0) {
ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
return rv;
nfr->fin = fr->fin;
nfr->stream_id = fr->stream_id;
nfr->offset = fr->offset;
- nfr->datacnt = acnt;
- ngtcp2_vec_copy(nfr->data, a, acnt);
+ nfr->datacnt = datacnt;
+ ngtcp2_vec_copy(nfr->data, data, datacnt);
ngtcp2_frame_chain_objalloc_del(frc, strm->frc_objalloc, strm->mem);
const ngtcp2_mem *mem;
int64_t stream_id;
void *stream_user_data;
- /* flags is bit-wise OR of zero or more of NGTCP2_STRM_FLAG_*. */
- uint32_t flags;
/* app_error_code is an error code the local endpoint sent in
RESET_STREAM or STOP_SENDING, or received from a remote endpoint
in RESET_STREAM or STOP_SENDING. First application error code is
chosen and when set, NGTCP2_STRM_FLAG_APP_ERROR_CODE_SET flag is
set in flags field. */
uint64_t app_error_code;
+ /* flags is bit-wise OR of zero or more of NGTCP2_STRM_FLAG_*. */
+ uint32_t flags;
};
ngtcp2_opl_entry oplent;
* * :member:`handshake_timeout <ngtcp2_settings.handshake_timeout>` =
* ``UINT64_MAX``
* * :member:`glitch_ratelim_burst
- * <ngtcp2_settings.glitch_ratelim_burst>` = 4000
+ * <ngtcp2_settings.glitch_ratelim_burst>` = 10000
* * :member:`glitch_ratelim_rate
- * <ngtcp2_settings.glitch_ratelim_rate>` = 132
+ * <ngtcp2_settings.glitch_ratelim_rate>` = 330
*/
NGTCP2_EXTERN void ngtcp2_settings_default_versioned(int settings_version,
ngtcp2_settings *settings);
*
* Version number of the ngtcp2 library release.
*/
-#define NGTCP2_VERSION "1.19.0"
+#define NGTCP2_VERSION "1.20.0"
/**
* @macro
* number, 8 bits for minor and 8 bits for patch. Version 1.2.3
* becomes 0x010203.
*/
-#define NGTCP2_VERSION_NUM 0x011300
+#define NGTCP2_VERSION_NUM 0x011400
#endif /* !defined(NGTCP2_VERSION_H) */