mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Add experimental support for delayed ACKs extension
This commit is contained in:
parent
df25d34a5e
commit
feca77f50d
21 changed files with 465 additions and 427 deletions
|
@ -258,6 +258,7 @@ IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||
enable_testing()
|
||||
ENDIF()
|
||||
|
||||
|
||||
FIND_PROGRAM(SPHINX NAMES sphinx-build)
|
||||
IF(SPHINX)
|
||||
ADD_CUSTOM_TARGET(docs
|
||||
|
|
|
@ -676,6 +676,15 @@ settings structure:
|
|||
|
||||
Default value is :macro:`LSQUIC_DF_SPIN`
|
||||
|
||||
.. member:: int es_delayed_acks
|
||||
|
||||
Enable delayed ACKs extension. Allowed values are 0 and 1.
|
||||
|
||||
**Warning**: this is an experimental feature. Using it will most likely
|
||||
lead to degraded performance.
|
||||
|
||||
Default value is :macro:`LSQUIC_DF_DELAYED_ACKS`
|
||||
|
||||
To initialize the settings structure to library defaults, use the following
|
||||
convenience function:
|
||||
|
||||
|
@ -846,6 +855,10 @@ out of date. Please check your :file:`lsquic.h` for actual values.*
|
|||
|
||||
Use Cubic by default.
|
||||
|
||||
.. macro:: LSQUIC_DF_DELAYED_ACKS
|
||||
|
||||
Delayed ACKs are off by default.
|
||||
|
||||
Receiving Packets
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -327,6 +327,9 @@ typedef struct ssl_ctx_st * (*lsquic_lookup_cert_f)(
|
|||
/** Turn spin bit on by default */
|
||||
#define LSQUIC_DF_SPIN 1
|
||||
|
||||
/** Turn off delayed ACKs extension by default */
|
||||
#define LSQUIC_DF_DELAYED_ACKS 0
|
||||
|
||||
/* 1: Cubic; 2: BBR */
|
||||
#define LSQUIC_DF_CC_ALGO 1
|
||||
|
||||
|
@ -711,6 +714,16 @@ struct lsquic_engine_settings {
|
|||
* Default value is @ref LSQUIC_DF_SPIN
|
||||
*/
|
||||
int es_spin;
|
||||
|
||||
/**
|
||||
* Enable delayed ACKs extension. Allowed values are 0 and 1.
|
||||
*
|
||||
* Warning: this is an experimental feature. Using it will most likely
|
||||
* lead to degraded performance.
|
||||
*
|
||||
* Default value is @ref LSQUIC_DF_DELAYED_ACKS
|
||||
*/
|
||||
int es_delayed_acks;
|
||||
};
|
||||
|
||||
/* Initialize `settings' to default values */
|
||||
|
|
|
@ -559,6 +559,11 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
params.tp_loss_bits = settings->es_ql_bits - 1;
|
||||
params.tp_set |= 1 << TPI_LOSS_BITS;
|
||||
}
|
||||
if (settings->es_delayed_acks)
|
||||
{
|
||||
params.tp_numerics[TPI_MIN_ACK_DELAY] = 10000; /* TODO: make into a constant? make configurable? */
|
||||
params.tp_set |= 1 << TPI_MIN_ACK_DELAY;
|
||||
}
|
||||
|
||||
len = lsquic_tp_encode(¶ms, enc_sess->esi_flags & ESI_SERVER, buf, bufsz);
|
||||
if (len >= 0)
|
||||
|
@ -1445,7 +1450,7 @@ get_peer_transport_params (struct enc_sess_iquic *enc_sess)
|
|||
struct transport_params *const trans_params = &enc_sess->esi_peer_tp;
|
||||
const uint8_t *params_buf;
|
||||
size_t bufsz;
|
||||
char params_str[0x200];
|
||||
char *params_str;
|
||||
|
||||
SSL_get_peer_quic_transport_params(enc_sess->esi_ssl, ¶ms_buf, &bufsz);
|
||||
if (!params_buf)
|
||||
|
@ -1459,9 +1464,20 @@ get_peer_transport_params (struct enc_sess_iquic *enc_sess)
|
|||
!(enc_sess->esi_flags & ESI_SERVER),
|
||||
trans_params))
|
||||
{
|
||||
lsquic_hexdump(params_buf, bufsz, params_str, sizeof(params_str));
|
||||
LSQ_DEBUG("could not parse peer transport parameters (%zd bytes):\n%s",
|
||||
bufsz, params_str);
|
||||
if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))
|
||||
{
|
||||
params_str = lsquic_mm_get_4k(&enc_sess->esi_enpub->enp_mm);
|
||||
if (params_str)
|
||||
{
|
||||
lsquic_hexdump(params_buf, bufsz, params_str, 0x1000);
|
||||
LSQ_DEBUG("could not parse peer transport parameters "
|
||||
"(%zd bytes):\n%s", bufsz, params_str);
|
||||
lsquic_mm_put_4k(&enc_sess->esi_enpub->enp_mm, params_str);
|
||||
}
|
||||
else
|
||||
LSQ_DEBUG("could not parse peer transport parameters "
|
||||
"(%zd bytes)", bufsz);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -334,6 +334,7 @@ lsquic_engine_init_settings (struct lsquic_engine_settings *settings,
|
|||
settings->es_allow_migration = LSQUIC_DF_ALLOW_MIGRATION;
|
||||
settings->es_ql_bits = LSQUIC_DF_QL_BITS;
|
||||
settings->es_spin = LSQUIC_DF_SPIN;
|
||||
settings->es_delayed_acks = LSQUIC_DF_DELAYED_ACKS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2185,7 +2185,9 @@ static unsigned
|
|||
process_packet_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
|
||||
const unsigned char *p, size_t len)
|
||||
{
|
||||
enum quic_frame_type type = conn->fc_conn.cn_pf->pf_parse_frame_type(p[0]);
|
||||
enum quic_frame_type type;
|
||||
|
||||
type = conn->fc_conn.cn_pf->pf_parse_frame_type(p, len);
|
||||
packet_in->pi_frame_types |= 1 << type;
|
||||
recent_packet_hist_frames(conn, 0, 1 << type);
|
||||
return process_frames[type](conn, packet_in, p, len);
|
||||
|
|
|
@ -5182,8 +5182,12 @@ static unsigned
|
|||
process_packet_frame (struct id24_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
enum enc_level enc_level = lsquic_packet_in_enc_level(packet_in);
|
||||
enum quic_frame_type type = conn->ifc_conn.cn_pf->pf_parse_frame_type(p[0]);
|
||||
enum enc_level enc_level;
|
||||
enum quic_frame_type type;
|
||||
char str[8 * 2 + 1];
|
||||
|
||||
enc_level = lsquic_packet_in_enc_level(packet_in);
|
||||
type = conn->ifc_conn.cn_pf->pf_parse_frame_type(p, len);
|
||||
if (lsquic_legal_frames_by_level[enc_level] & (1 << type))
|
||||
{
|
||||
LSQ_DEBUG("about to process %s frame", frame_type_2_str[type]);
|
||||
|
@ -5192,8 +5196,8 @@ process_packet_frame (struct id24_full_conn *conn,
|
|||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("invalid frame %u (byte=0x%02X) at encryption level %s",
|
||||
type, p[0], lsquic_enclev2str[enc_level]);
|
||||
LSQ_DEBUG("invalid frame %u (bytes: %s) at encryption level %s",
|
||||
type, HEXSTR(p, MIN(len, 8), str), lsquic_enclev2str[enc_level]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@ enum ifull_conn_flags
|
|||
IFC_PROC_CRYPTO = 1 << 26,
|
||||
IFC_MIGRA = 1 << 27,
|
||||
IFC_SPIN = 1 << 28, /* Spin bits are enabled */
|
||||
IFC_DELAYED_ACKS = 1 << 29, /* Delayed ACKs are enabled */
|
||||
};
|
||||
|
||||
|
||||
|
@ -161,6 +162,7 @@ enum send
|
|||
SEND_MAX_STREAMS_UNI = SEND_MAX_STREAMS + SD_UNI,
|
||||
SEND_STOP_SENDING,
|
||||
SEND_HANDSHAKE_DONE,
|
||||
SEND_ACK_FREQUENCY,
|
||||
N_SEND
|
||||
};
|
||||
|
||||
|
@ -185,6 +187,7 @@ enum send_flags
|
|||
SF_SEND_MAX_STREAMS_UNI = 1 << SEND_MAX_STREAMS_UNI,
|
||||
SF_SEND_STOP_SENDING = 1 << SEND_STOP_SENDING,
|
||||
SF_SEND_HANDSHAKE_DONE = 1 << SEND_HANDSHAKE_DONE,
|
||||
SF_SEND_ACK_FREQUENCY = 1 << SEND_ACK_FREQUENCY,
|
||||
};
|
||||
|
||||
#define SF_SEND_PATH_CHAL_ALL \
|
||||
|
@ -283,6 +286,14 @@ struct conn_path
|
|||
};
|
||||
|
||||
|
||||
struct inc_ack_stats /* Incoming ACK stats */
|
||||
{
|
||||
unsigned n_acks; /* Number of ACKs between ticks */
|
||||
float avg_acked; /* Packets acked between ticks */
|
||||
float avg_n_acks; /* Average number of ACKs */
|
||||
};
|
||||
|
||||
|
||||
struct ietf_full_conn
|
||||
{
|
||||
struct lsquic_conn ifc_conn;
|
||||
|
@ -336,6 +347,7 @@ struct ietf_full_conn
|
|||
/* Number ackable packets received since last ACK was sent: */
|
||||
unsigned ifc_n_slack_akbl[N_PNS];
|
||||
unsigned ifc_n_slack_all; /* App PNS only */
|
||||
unsigned ifc_max_retx_since_last_ack;
|
||||
uint64_t ifc_ecn_counts_in[N_PNS][4];
|
||||
uint64_t ifc_ecn_counts_out[N_PNS][4];
|
||||
lsquic_stream_id_t ifc_max_req_id;
|
||||
|
@ -368,6 +380,10 @@ struct ietf_full_conn
|
|||
unsigned char ifc_first_active_cid_seqno;
|
||||
unsigned char ifc_ping_unretx_thresh;
|
||||
unsigned ifc_last_retire_prior_to;
|
||||
unsigned ifc_ack_freq_seqno;
|
||||
unsigned ifc_last_pack_tol;
|
||||
unsigned ifc_max_ack_freq_seqno; /* Incoming */
|
||||
unsigned ifc_max_peer_ack_usec;
|
||||
lsquic_time_t ifc_last_live_update;
|
||||
struct conn_path ifc_paths[N_PATHS];
|
||||
union {
|
||||
|
@ -394,6 +410,7 @@ struct ietf_full_conn
|
|||
lsquic_time_t ifc_idle_to;
|
||||
lsquic_time_t ifc_ping_period;
|
||||
uint64_t ifc_last_max_data_off_sent;
|
||||
struct inc_ack_stats ifc_ias;
|
||||
struct ack_info ifc_ack;
|
||||
};
|
||||
|
||||
|
@ -1073,6 +1090,7 @@ ietf_full_conn_init (struct ietf_full_conn *conn,
|
|||
#define valid_stream_id(v) ((v) <= VINT_MAX_VALUE)
|
||||
conn->ifc_max_req_id = VINT_MAX_VALUE + 1;
|
||||
conn->ifc_ping_unretx_thresh = 20;
|
||||
conn->ifc_max_retx_since_last_ack = MAX_RETR_PACKETS_SINCE_LAST_ACK;
|
||||
maybe_enable_spin(conn);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2992,6 +3010,16 @@ handshake_ok (struct lsquic_conn *lconn)
|
|||
conn->ifc_ping_period = 0;
|
||||
LSQ_DEBUG("PING period is set to %"PRIu64" usec", conn->ifc_ping_period);
|
||||
|
||||
if (conn->ifc_conn.cn_version > LSQVER_ID24
|
||||
&& conn->ifc_settings->es_delayed_acks
|
||||
&& (params->tp_set & (1 << TPI_MIN_ACK_DELAY)))
|
||||
{
|
||||
LSQ_DEBUG("delayed ACKs enabled");
|
||||
conn->ifc_flags |= IFC_DELAYED_ACKS;
|
||||
}
|
||||
|
||||
conn->ifc_max_peer_ack_usec = params->tp_max_ack_delay * 1000;
|
||||
|
||||
/* TODO: packet size */
|
||||
|
||||
dce = get_new_dce(conn);
|
||||
|
@ -3844,6 +3872,40 @@ generate_handshake_done_frame (struct ietf_full_conn *conn,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_ack_frequency_frame (struct ietf_full_conn *conn, lsquic_time_t unused)
|
||||
{
|
||||
struct lsquic_packet_out *packet_out;
|
||||
unsigned need;
|
||||
int sz;
|
||||
|
||||
need = conn->ifc_conn.cn_pf->pf_ack_frequency_frame_size(
|
||||
conn->ifc_ack_freq_seqno, 2, ACK_TIMEOUT);
|
||||
packet_out = get_writeable_packet(conn, need);
|
||||
if (!packet_out)
|
||||
{
|
||||
LSQ_DEBUG("cannot get writeable packet for ACK_FREQUENCY frame");
|
||||
return;
|
||||
}
|
||||
|
||||
conn->ifc_last_pack_tol = conn->ifc_ias.avg_acked;
|
||||
sz = conn->ifc_conn.cn_pf->pf_gen_ack_frequency_frame(
|
||||
packet_out->po_data + packet_out->po_data_sz,
|
||||
lsquic_packet_out_avail(packet_out),
|
||||
conn->ifc_ack_freq_seqno, conn->ifc_last_pack_tol,
|
||||
conn->ifc_max_peer_ack_usec);
|
||||
if (sz < 0)
|
||||
{
|
||||
ABORT_ERROR("gen_rst_frame failed");
|
||||
return;
|
||||
}
|
||||
lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, sz);
|
||||
packet_out->po_frame_types |= QUIC_FTBIT_ACK_FREQUENCY;
|
||||
++conn->ifc_ack_freq_seqno;
|
||||
conn->ifc_send_flags &= ~SF_SEND_ACK_FREQUENCY;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_path_chal_frame (struct ietf_full_conn *conn, lsquic_time_t now,
|
||||
unsigned path_id)
|
||||
|
@ -4073,16 +4135,55 @@ handshake_confirmed (struct ietf_full_conn *conn)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
update_ema (float *val, unsigned new)
|
||||
{
|
||||
if (*val)
|
||||
*val = (new - *val) * 0.4 + *val;
|
||||
else
|
||||
*val = new;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_target_packet_tolerance (struct ietf_full_conn *conn,
|
||||
const unsigned n_newly_acked)
|
||||
{
|
||||
update_ema(&conn->ifc_ias.avg_n_acks, conn->ifc_ias.n_acks);
|
||||
update_ema(&conn->ifc_ias.avg_acked, n_newly_acked);
|
||||
LSQ_DEBUG("packtol logic: %u ACK frames (avg: %.2f), %u newly acked "
|
||||
"(avg: %.1f), last sent %u", conn->ifc_ias.n_acks,
|
||||
conn->ifc_ias.avg_n_acks, n_newly_acked, conn->ifc_ias.avg_acked,
|
||||
conn->ifc_last_pack_tol);
|
||||
if (conn->ifc_ias.avg_n_acks > 1.5 && conn->ifc_ias.avg_acked > 2.0
|
||||
&& conn->ifc_ias.avg_acked > (float) conn->ifc_last_pack_tol)
|
||||
{
|
||||
LSQ_DEBUG("old packet tolerance target: %u, schedule ACK_FREQUENCY "
|
||||
"increase", conn->ifc_last_pack_tol);
|
||||
conn->ifc_send_flags |= SF_SEND_ACK_FREQUENCY;
|
||||
}
|
||||
else if (conn->ifc_ias.avg_n_acks < 1.5
|
||||
&& conn->ifc_ias.avg_acked < (float) conn->ifc_last_pack_tol * 3 / 4)
|
||||
{
|
||||
LSQ_DEBUG("old packet tolerance target: %u, schedule ACK_FREQUENCY "
|
||||
"decrease", conn->ifc_last_pack_tol);
|
||||
conn->ifc_send_flags |= SF_SEND_ACK_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
process_ack (struct ietf_full_conn *conn, struct ack_info *acki,
|
||||
lsquic_time_t received, lsquic_time_t now)
|
||||
{
|
||||
enum packnum_space pns;
|
||||
lsquic_packno_t packno;
|
||||
unsigned n_unacked;
|
||||
int one_rtt_acked;
|
||||
|
||||
LSQ_DEBUG("Processing ACK");
|
||||
one_rtt_acked = lsquic_send_ctl_1rtt_acked(&conn->ifc_send_ctl);
|
||||
n_unacked = lsquic_send_ctl_n_unacked(&conn->ifc_send_ctl);
|
||||
if (0 == lsquic_send_ctl_got_ack(&conn->ifc_send_ctl, acki, received, now))
|
||||
{
|
||||
pns = acki->pns;
|
||||
|
@ -4097,6 +4198,9 @@ process_ack (struct ietf_full_conn *conn, struct ack_info *acki,
|
|||
ignore_init(conn);
|
||||
handshake_confirmed(conn);
|
||||
}
|
||||
if (PNS_APP == pns && (conn->ifc_flags & IFC_DELAYED_ACKS))
|
||||
update_target_packet_tolerance(conn,
|
||||
n_unacked - lsquic_send_ctl_n_unacked(&conn->ifc_send_ctl));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
@ -4851,13 +4955,17 @@ process_ack_frame (struct ietf_full_conn *conn,
|
|||
LSQ_DEBUG("Saved ACK");
|
||||
conn->ifc_flags |= IFC_HAVE_SAVED_ACK;
|
||||
conn->ifc_saved_ack_received = packet_in->pi_received;
|
||||
conn->ifc_ias.n_acks = 1;
|
||||
}
|
||||
else if (pns == PNS_APP)
|
||||
{
|
||||
if (0 == lsquic_merge_acks(&conn->ifc_ack, new_acki))
|
||||
{
|
||||
++conn->ifc_ias.n_acks;
|
||||
LSQ_DEBUG("merged into saved ACK, getting %s",
|
||||
(lsquic_acki2str(&conn->ifc_ack, conn->ifc_pub.mm->ack_str,
|
||||
MAX_ACKI_STR_SZ), conn->ifc_pub.mm->ack_str));
|
||||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("could not merge new ACK into saved ACK");
|
||||
|
@ -5294,8 +5402,6 @@ process_new_token_frame (struct ietf_full_conn *conn,
|
|||
char *token_str;
|
||||
int parsed_len;
|
||||
|
||||
/* TODO: make receipt of NEW_TOKEN frame an error on the server */
|
||||
|
||||
parsed_len = conn->ifc_conn.cn_pf->pf_parse_new_token_frame(p, len, &token,
|
||||
&token_sz);
|
||||
if (parsed_len < 0)
|
||||
|
@ -5454,6 +5560,58 @@ process_handshake_done_frame (struct ietf_full_conn *conn,
|
|||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
process_ack_frequency_frame (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
uint64_t seqno, pack_tol, upd_mad;
|
||||
int parsed_len;
|
||||
|
||||
if (!(conn->ifc_flags & IFC_DELAYED_ACKS))
|
||||
{
|
||||
ABORT_QUIETLY(0, TEC_PROTOCOL_VIOLATION,
|
||||
"Received unexpected ACK_FREQUENCY frame (not negotiated)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
parsed_len = conn->ifc_conn.cn_pf->pf_parse_ack_frequency_frame(p, len,
|
||||
&seqno, &pack_tol, &upd_mad);
|
||||
if (parsed_len < 0)
|
||||
return 0;
|
||||
|
||||
EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "ACK_FREQUENCY(seqno: %"PRIu64"; "
|
||||
"pack_tol: %"PRIu64"; upd: %"PRIu64") frame in", seqno, pack_tol,
|
||||
upd_mad);
|
||||
LSQ_DEBUG("ACK_FREQUENCY(seqno: %"PRIu64"; pack_tol: %"PRIu64"; "
|
||||
"upd: %"PRIu64") frame in", seqno, pack_tol, upd_mad);
|
||||
|
||||
if (pack_tol == 0)
|
||||
{
|
||||
ABORT_QUIETLY(0, TEC_PROTOCOL_VIOLATION,
|
||||
"Packet Tolerance of zero is invalid");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (conn->ifc_max_ack_freq_seqno > 0
|
||||
&& seqno <= conn->ifc_max_ack_freq_seqno)
|
||||
{
|
||||
LSQ_DEBUG("ignore old ACK_FREQUENCY frame");
|
||||
return parsed_len;
|
||||
}
|
||||
conn->ifc_max_ack_freq_seqno = seqno;
|
||||
|
||||
if (pack_tol < UINT_MAX)
|
||||
{
|
||||
LSQ_DEBUG("set packet tolerance to %"PRIu64, pack_tol);
|
||||
conn->ifc_max_retx_since_last_ack = pack_tol;
|
||||
}
|
||||
|
||||
/* TODO: do something with max ack delay update */
|
||||
|
||||
return parsed_len;
|
||||
}
|
||||
|
||||
|
||||
typedef unsigned (*process_frame_f)(
|
||||
struct ietf_full_conn *, struct lsquic_packet_in *,
|
||||
const unsigned char *p, size_t);
|
||||
|
@ -5481,6 +5639,7 @@ static process_frame_f const process_frames[N_QUIC_FRAMES] =
|
|||
[QUIC_FRAME_STREAM] = process_stream_frame,
|
||||
[QUIC_FRAME_CRYPTO] = process_crypto_frame,
|
||||
[QUIC_FRAME_HANDSHAKE_DONE] = process_handshake_done_frame,
|
||||
[QUIC_FRAME_ACK_FREQUENCY] = process_ack_frequency_frame,
|
||||
};
|
||||
|
||||
|
||||
|
@ -5488,8 +5647,12 @@ static unsigned
|
|||
process_packet_frame (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
enum enc_level enc_level = lsquic_packet_in_enc_level(packet_in);
|
||||
enum quic_frame_type type = conn->ifc_conn.cn_pf->pf_parse_frame_type(p[0]);
|
||||
enum enc_level enc_level;
|
||||
enum quic_frame_type type;
|
||||
char str[8 * 2 + 1];
|
||||
|
||||
enc_level = lsquic_packet_in_enc_level(packet_in);
|
||||
type = conn->ifc_conn.cn_pf->pf_parse_frame_type(p, len);
|
||||
if (lsquic_legal_frames_by_level[enc_level] & (1 << type))
|
||||
{
|
||||
LSQ_DEBUG("about to process %s frame", frame_type_2_str[type]);
|
||||
|
@ -5498,8 +5661,8 @@ process_packet_frame (struct ietf_full_conn *conn,
|
|||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("invalid frame %u (byte=0x%02X) at encryption level %s",
|
||||
type, p[0], lsquic_enclev2str[enc_level]);
|
||||
LSQ_DEBUG("invalid frame %u (bytes: %s) at encryption level %s",
|
||||
type, HEXSTR(p, MIN(len, 8), str), lsquic_enclev2str[enc_level]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -5684,7 +5847,7 @@ try_queueing_ack_app (struct ietf_full_conn *conn,
|
|||
{
|
||||
lsquic_time_t srtt, ack_timeout;
|
||||
|
||||
if (conn->ifc_n_slack_akbl[PNS_APP] >= MAX_RETR_PACKETS_SINCE_LAST_ACK
|
||||
if (conn->ifc_n_slack_akbl[PNS_APP] >= conn->ifc_max_retx_since_last_ack
|
||||
|| ((conn->ifc_flags & IFC_ACK_HAD_MISS)
|
||||
&& was_missing && conn->ifc_n_slack_akbl[PNS_APP] > 0)
|
||||
|| many_in_and_will_write(conn))
|
||||
|
@ -6363,6 +6526,7 @@ static void (*const send_funcs[N_SEND])(
|
|||
[SEND_PATH_RESP_PATH_1] = generate_path_resp_1,
|
||||
[SEND_PING] = generate_ping_frame,
|
||||
[SEND_HANDSHAKE_DONE] = generate_handshake_done_frame,
|
||||
[SEND_ACK_FREQUENCY] = generate_ack_frequency_frame,
|
||||
};
|
||||
|
||||
|
||||
|
@ -6373,6 +6537,7 @@ static void (*const send_funcs[N_SEND])(
|
|||
|SF_SEND_PATH_CHAL_PATH_0|SF_SEND_PATH_CHAL_PATH_1\
|
||||
|SF_SEND_PATH_RESP_PATH_0|SF_SEND_PATH_RESP_PATH_1\
|
||||
|SF_SEND_PING|SF_SEND_HANDSHAKE_DONE\
|
||||
|SF_SEND_ACK_FREQUENCY\
|
||||
|SF_SEND_STOP_SENDING)
|
||||
|
||||
static enum tick_st
|
||||
|
|
|
@ -656,7 +656,7 @@ static unsigned
|
|||
process_packet_frame (struct mini_conn *mc, lsquic_packet_in_t *packet_in,
|
||||
const unsigned char *p, size_t len)
|
||||
{
|
||||
enum quic_frame_type type = mc->mc_conn.cn_pf->pf_parse_frame_type(p[0]);
|
||||
enum quic_frame_type type = mc->mc_conn.cn_pf->pf_parse_frame_type(p, len);
|
||||
packet_in->pi_frame_types |= 1 << type;
|
||||
return process_frames[type](mc, packet_in, p, len);
|
||||
}
|
||||
|
@ -761,7 +761,7 @@ process_regular_packet (struct mini_conn *mc, lsquic_packet_in_t *packet_in)
|
|||
p += len;
|
||||
else
|
||||
{
|
||||
if (mc->mc_conn.cn_pf->pf_parse_frame_type(p[0]) !=
|
||||
if (mc->mc_conn.cn_pf->pf_parse_frame_type(p, pend - p) !=
|
||||
QUIC_FRAME_CONNECTION_CLOSE)
|
||||
LSQ_WARN("error parsing frame: packno %"PRIu64"; sz: %u; type: "
|
||||
"0x%X", packet_in->pi_packno, packet_in->pi_data_sz, p[0]);
|
||||
|
|
|
@ -1019,7 +1019,7 @@ static unsigned
|
|||
imico_process_invalid_frame (IMICO_PROC_FRAME_ARGS)
|
||||
{
|
||||
LSQ_DEBUG("invalid frame %u (%s)", p[0],
|
||||
frame_type_2_str[ conn->imc_conn.cn_pf->pf_parse_frame_type(p[0]) ]);
|
||||
frame_type_2_str[ conn->imc_conn.cn_pf->pf_parse_frame_type(p, len) ]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1056,8 +1056,11 @@ static unsigned
|
|||
imico_process_packet_frame (struct ietf_mini_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
enum enc_level enc_level = lsquic_packet_in_enc_level(packet_in);
|
||||
enum quic_frame_type type = conn->imc_conn.cn_pf->pf_parse_frame_type(p[0]);
|
||||
enum enc_level enc_level;
|
||||
enum quic_frame_type type;
|
||||
|
||||
enc_level = lsquic_packet_in_enc_level(packet_in);
|
||||
type = conn->imc_conn.cn_pf->pf_parse_frame_type(p, len);
|
||||
if (lsquic_legal_frames_by_level[enc_level] & (1 << type))
|
||||
{
|
||||
packet_in->pi_frame_types |= 1 << type;
|
||||
|
|
|
@ -34,6 +34,7 @@ enum quic_frame_type
|
|||
QUIC_FRAME_RETIRE_CONNECTION_ID,/* I */
|
||||
QUIC_FRAME_NEW_TOKEN, /* I */
|
||||
QUIC_FRAME_HANDSHAKE_DONE, /* I */
|
||||
QUIC_FRAME_ACK_FREQUENCY, /* I */
|
||||
N_QUIC_FRAMES
|
||||
};
|
||||
|
||||
|
@ -62,6 +63,7 @@ enum quic_ft_bit {
|
|||
QUIC_FTBIT_NEW_TOKEN = 1 << QUIC_FRAME_NEW_TOKEN,
|
||||
QUIC_FTBIT_RETIRE_CONNECTION_ID = 1 << QUIC_FRAME_RETIRE_CONNECTION_ID,
|
||||
QUIC_FTBIT_HANDSHAKE_DONE = 1 << QUIC_FRAME_HANDSHAKE_DONE,
|
||||
QUIC_FTBIT_ACK_FREQUENCY = 1 << QUIC_FRAME_ACK_FREQUENCY,
|
||||
};
|
||||
|
||||
static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
|
||||
|
@ -89,6 +91,7 @@ static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
|
|||
[QUIC_FRAME_NEW_TOKEN] = "QUIC_FRAME_NEW_TOKEN",
|
||||
[QUIC_FRAME_RETIRE_CONNECTION_ID] = "QUIC_FRAME_RETIRE_CONNECTION_ID",
|
||||
[QUIC_FRAME_HANDSHAKE_DONE] = "QUIC_FRAME_HANDSHAKE_DONE",
|
||||
[QUIC_FRAME_ACK_FREQUENCY] = "QUIC_FRAME_ACK_FREQUENCY",
|
||||
};
|
||||
|
||||
#define QUIC_FRAME_PRELEN (sizeof("QUIC_FRAME_"))
|
||||
|
@ -124,6 +127,7 @@ static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
|
|||
+ 1 + \
|
||||
QUIC_FRAME_SLEN(QUIC_FRAME_NEW_TOKEN) + 1 + \
|
||||
QUIC_FRAME_SLEN(QUIC_FRAME_HANDSHAKE_DONE) + 1 + \
|
||||
QUIC_FRAME_SLEN(QUIC_FRAME_ACK_FREQUENCY) + 1 + \
|
||||
0
|
||||
|
||||
|
||||
|
@ -212,6 +216,7 @@ extern const char *const lsquic_pns2str[];
|
|||
| QUIC_FTBIT_RETIRE_CONNECTION_ID \
|
||||
| QUIC_FTBIT_NEW_TOKEN \
|
||||
| QUIC_FTBIT_HANDSHAKE_DONE \
|
||||
| QUIC_FTBIT_ACK_FREQUENCY \
|
||||
| QUIC_FTBIT_CRYPTO )
|
||||
|
||||
/* [draft-ietf-quic-transport-24] Section 1.2 */
|
||||
|
|
|
@ -76,7 +76,7 @@ struct parse_funcs
|
|||
(*pf_parse_packet_in_finish) (struct lsquic_packet_in *packet_in,
|
||||
struct packin_parse_state *);
|
||||
enum quic_frame_type
|
||||
(*pf_parse_frame_type) (unsigned char);
|
||||
(*pf_parse_frame_type) (const unsigned char *, size_t);
|
||||
/* Return used buffer length or a negative value if there was not enough
|
||||
* room to write the stream frame. In the latter case, the negative of
|
||||
* the negative return value is the number of bytes required. The
|
||||
|
@ -301,6 +301,15 @@ struct parse_funcs
|
|||
(*pf_parse_handshake_done_frame) (const unsigned char *buf, size_t buf_len);
|
||||
unsigned
|
||||
(*pf_handshake_done_frame_size) (void);
|
||||
int
|
||||
(*pf_gen_ack_frequency_frame) (unsigned char *buf, size_t buf_len,
|
||||
uint64_t seqno, uint64_t pack_tol, uint64_t upd_mad);
|
||||
int
|
||||
(*pf_parse_ack_frequency_frame) (const unsigned char *buf, size_t buf_len,
|
||||
uint64_t *seqno, uint64_t *pack_tol, uint64_t *upd_mad);
|
||||
unsigned
|
||||
(*pf_ack_frequency_frame_size) (uint64_t seqno, uint64_t pack_tol,
|
||||
uint64_t upd_mad);
|
||||
};
|
||||
|
||||
|
||||
|
@ -339,9 +348,9 @@ lsquic_Q050_parse_packet_in_long_begin (struct lsquic_packet_in *, size_t length
|
|||
int is_server, unsigned, struct packin_parse_state *);
|
||||
|
||||
enum quic_frame_type
|
||||
lsquic_parse_frame_type_gquic_Q035_thru_Q046 (unsigned char first_byte);
|
||||
lsquic_parse_frame_type_gquic_Q035_thru_Q046 (const unsigned char *, size_t);
|
||||
|
||||
extern const enum quic_frame_type lsquic_iquic_byte2type[0x100];
|
||||
extern const enum quic_frame_type lsquic_iquic_byte2type[0x40];
|
||||
|
||||
size_t
|
||||
calc_stream_frame_header_sz_gquic (lsquic_stream_id_t stream_id,
|
||||
|
|
|
@ -785,9 +785,12 @@ static const enum quic_frame_type byte2frame_type_Q050[0x100] =
|
|||
|
||||
|
||||
static enum quic_frame_type
|
||||
gquic_Q050_parse_frame_type (unsigned char b)
|
||||
gquic_Q050_parse_frame_type (const unsigned char *buf, size_t len)
|
||||
{
|
||||
return byte2frame_type_Q050[b];
|
||||
if (len > 0)
|
||||
return byte2frame_type_Q050[buf[0]];
|
||||
else
|
||||
return QUIC_FRAME_INVALID;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -242,6 +242,6 @@ const enum quic_ft_bit lsquic_legal_frames_by_level[N_ENC_LEVS] =
|
|||
| QUIC_FTBIT_STREAMS_BLOCKED
|
||||
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
|
||||
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
|
||||
| QUIC_FTBIT_HANDSHAKE_DONE
|
||||
| QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
|
||||
| QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN,
|
||||
};
|
||||
|
|
|
@ -458,9 +458,13 @@ static const enum quic_frame_type byte2frame_type_Q035_thru_Q046[0x100] =
|
|||
|
||||
|
||||
enum quic_frame_type
|
||||
lsquic_parse_frame_type_gquic_Q035_thru_Q046 (unsigned char b)
|
||||
lsquic_parse_frame_type_gquic_Q035_thru_Q046 (const unsigned char *buf,
|
||||
size_t len)
|
||||
{
|
||||
return byte2frame_type_Q035_thru_Q046[b];
|
||||
if (len > 0)
|
||||
return byte2frame_type_Q035_thru_Q046[buf[0]];
|
||||
else
|
||||
return QUIC_FRAME_INVALID;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1097,17 +1097,31 @@ ietf_v1_calc_crypto_frame_header_sz (uint64_t offset, unsigned data_sz)
|
|||
|
||||
|
||||
static enum quic_frame_type
|
||||
ietf_v1_parse_frame_type (unsigned char byte)
|
||||
ietf_v1_parse_frame_type (const unsigned char *buf, size_t len)
|
||||
{
|
||||
return lsquic_iquic_byte2type[byte];
|
||||
uint64_t val;
|
||||
int s;
|
||||
|
||||
if (len > 0 && buf[0] < 0x40)
|
||||
return lsquic_iquic_byte2type[buf[0]];
|
||||
|
||||
s = vint_read(buf, buf + len, &val);
|
||||
if (s > 0 && (unsigned) s == (1u << vint_val2bits(val)))
|
||||
switch (val)
|
||||
{
|
||||
case 0xAF: return QUIC_FRAME_ACK_FREQUENCY;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return QUIC_FRAME_INVALID;
|
||||
}
|
||||
|
||||
|
||||
static enum quic_frame_type
|
||||
ietf_id24_parse_frame_type (unsigned char byte)
|
||||
ietf_id24_parse_frame_type (const unsigned char *buf, size_t len)
|
||||
{
|
||||
/* This one does not have QUIC_FRAME_HANDSHAKE_DONE */
|
||||
static const enum quic_frame_type byte2type[0x100] =
|
||||
static const enum quic_frame_type byte2type[0x40] =
|
||||
{
|
||||
[0x00] = QUIC_FRAME_PADDING,
|
||||
[0x01] = QUIC_FRAME_PING,
|
||||
|
@ -1173,200 +1187,12 @@ ietf_id24_parse_frame_type (unsigned char byte)
|
|||
[0x3D] = QUIC_FRAME_INVALID,
|
||||
[0x3E] = QUIC_FRAME_INVALID,
|
||||
[0x3F] = QUIC_FRAME_INVALID,
|
||||
[0x40] = QUIC_FRAME_INVALID,
|
||||
[0x41] = QUIC_FRAME_INVALID,
|
||||
[0x42] = QUIC_FRAME_INVALID,
|
||||
[0x43] = QUIC_FRAME_INVALID,
|
||||
[0x44] = QUIC_FRAME_INVALID,
|
||||
[0x45] = QUIC_FRAME_INVALID,
|
||||
[0x46] = QUIC_FRAME_INVALID,
|
||||
[0x47] = QUIC_FRAME_INVALID,
|
||||
[0x48] = QUIC_FRAME_INVALID,
|
||||
[0x49] = QUIC_FRAME_INVALID,
|
||||
[0x4A] = QUIC_FRAME_INVALID,
|
||||
[0x4B] = QUIC_FRAME_INVALID,
|
||||
[0x4C] = QUIC_FRAME_INVALID,
|
||||
[0x4D] = QUIC_FRAME_INVALID,
|
||||
[0x4E] = QUIC_FRAME_INVALID,
|
||||
[0x4F] = QUIC_FRAME_INVALID,
|
||||
[0x50] = QUIC_FRAME_INVALID,
|
||||
[0x51] = QUIC_FRAME_INVALID,
|
||||
[0x52] = QUIC_FRAME_INVALID,
|
||||
[0x53] = QUIC_FRAME_INVALID,
|
||||
[0x54] = QUIC_FRAME_INVALID,
|
||||
[0x55] = QUIC_FRAME_INVALID,
|
||||
[0x56] = QUIC_FRAME_INVALID,
|
||||
[0x57] = QUIC_FRAME_INVALID,
|
||||
[0x58] = QUIC_FRAME_INVALID,
|
||||
[0x59] = QUIC_FRAME_INVALID,
|
||||
[0x5A] = QUIC_FRAME_INVALID,
|
||||
[0x5B] = QUIC_FRAME_INVALID,
|
||||
[0x5C] = QUIC_FRAME_INVALID,
|
||||
[0x5D] = QUIC_FRAME_INVALID,
|
||||
[0x5E] = QUIC_FRAME_INVALID,
|
||||
[0x5F] = QUIC_FRAME_INVALID,
|
||||
[0x60] = QUIC_FRAME_INVALID,
|
||||
[0x61] = QUIC_FRAME_INVALID,
|
||||
[0x62] = QUIC_FRAME_INVALID,
|
||||
[0x63] = QUIC_FRAME_INVALID,
|
||||
[0x64] = QUIC_FRAME_INVALID,
|
||||
[0x65] = QUIC_FRAME_INVALID,
|
||||
[0x66] = QUIC_FRAME_INVALID,
|
||||
[0x67] = QUIC_FRAME_INVALID,
|
||||
[0x68] = QUIC_FRAME_INVALID,
|
||||
[0x69] = QUIC_FRAME_INVALID,
|
||||
[0x6A] = QUIC_FRAME_INVALID,
|
||||
[0x6B] = QUIC_FRAME_INVALID,
|
||||
[0x6C] = QUIC_FRAME_INVALID,
|
||||
[0x6D] = QUIC_FRAME_INVALID,
|
||||
[0x6E] = QUIC_FRAME_INVALID,
|
||||
[0x6F] = QUIC_FRAME_INVALID,
|
||||
[0x70] = QUIC_FRAME_INVALID,
|
||||
[0x71] = QUIC_FRAME_INVALID,
|
||||
[0x72] = QUIC_FRAME_INVALID,
|
||||
[0x73] = QUIC_FRAME_INVALID,
|
||||
[0x74] = QUIC_FRAME_INVALID,
|
||||
[0x75] = QUIC_FRAME_INVALID,
|
||||
[0x76] = QUIC_FRAME_INVALID,
|
||||
[0x77] = QUIC_FRAME_INVALID,
|
||||
[0x78] = QUIC_FRAME_INVALID,
|
||||
[0x79] = QUIC_FRAME_INVALID,
|
||||
[0x7A] = QUIC_FRAME_INVALID,
|
||||
[0x7B] = QUIC_FRAME_INVALID,
|
||||
[0x7C] = QUIC_FRAME_INVALID,
|
||||
[0x7D] = QUIC_FRAME_INVALID,
|
||||
[0x7E] = QUIC_FRAME_INVALID,
|
||||
[0x7F] = QUIC_FRAME_INVALID,
|
||||
[0x80] = QUIC_FRAME_INVALID,
|
||||
[0x81] = QUIC_FRAME_INVALID,
|
||||
[0x82] = QUIC_FRAME_INVALID,
|
||||
[0x83] = QUIC_FRAME_INVALID,
|
||||
[0x84] = QUIC_FRAME_INVALID,
|
||||
[0x85] = QUIC_FRAME_INVALID,
|
||||
[0x86] = QUIC_FRAME_INVALID,
|
||||
[0x87] = QUIC_FRAME_INVALID,
|
||||
[0x88] = QUIC_FRAME_INVALID,
|
||||
[0x89] = QUIC_FRAME_INVALID,
|
||||
[0x8A] = QUIC_FRAME_INVALID,
|
||||
[0x8B] = QUIC_FRAME_INVALID,
|
||||
[0x8C] = QUIC_FRAME_INVALID,
|
||||
[0x8D] = QUIC_FRAME_INVALID,
|
||||
[0x8E] = QUIC_FRAME_INVALID,
|
||||
[0x8F] = QUIC_FRAME_INVALID,
|
||||
[0x90] = QUIC_FRAME_INVALID,
|
||||
[0x91] = QUIC_FRAME_INVALID,
|
||||
[0x92] = QUIC_FRAME_INVALID,
|
||||
[0x93] = QUIC_FRAME_INVALID,
|
||||
[0x94] = QUIC_FRAME_INVALID,
|
||||
[0x95] = QUIC_FRAME_INVALID,
|
||||
[0x96] = QUIC_FRAME_INVALID,
|
||||
[0x97] = QUIC_FRAME_INVALID,
|
||||
[0x98] = QUIC_FRAME_INVALID,
|
||||
[0x99] = QUIC_FRAME_INVALID,
|
||||
[0x9A] = QUIC_FRAME_INVALID,
|
||||
[0x9B] = QUIC_FRAME_INVALID,
|
||||
[0x9C] = QUIC_FRAME_INVALID,
|
||||
[0x9D] = QUIC_FRAME_INVALID,
|
||||
[0x9E] = QUIC_FRAME_INVALID,
|
||||
[0x9F] = QUIC_FRAME_INVALID,
|
||||
[0xA0] = QUIC_FRAME_INVALID,
|
||||
[0xA1] = QUIC_FRAME_INVALID,
|
||||
[0xA2] = QUIC_FRAME_INVALID,
|
||||
[0xA3] = QUIC_FRAME_INVALID,
|
||||
[0xA4] = QUIC_FRAME_INVALID,
|
||||
[0xA5] = QUIC_FRAME_INVALID,
|
||||
[0xA6] = QUIC_FRAME_INVALID,
|
||||
[0xA7] = QUIC_FRAME_INVALID,
|
||||
[0xA8] = QUIC_FRAME_INVALID,
|
||||
[0xA9] = QUIC_FRAME_INVALID,
|
||||
[0xAA] = QUIC_FRAME_INVALID,
|
||||
[0xAB] = QUIC_FRAME_INVALID,
|
||||
[0xAC] = QUIC_FRAME_INVALID,
|
||||
[0xAD] = QUIC_FRAME_INVALID,
|
||||
[0xAE] = QUIC_FRAME_INVALID,
|
||||
[0xAF] = QUIC_FRAME_INVALID,
|
||||
[0xB0] = QUIC_FRAME_INVALID,
|
||||
[0xB1] = QUIC_FRAME_INVALID,
|
||||
[0xB2] = QUIC_FRAME_INVALID,
|
||||
[0xB3] = QUIC_FRAME_INVALID,
|
||||
[0xB4] = QUIC_FRAME_INVALID,
|
||||
[0xB5] = QUIC_FRAME_INVALID,
|
||||
[0xB6] = QUIC_FRAME_INVALID,
|
||||
[0xB7] = QUIC_FRAME_INVALID,
|
||||
[0xB8] = QUIC_FRAME_INVALID,
|
||||
[0xB9] = QUIC_FRAME_INVALID,
|
||||
[0xBA] = QUIC_FRAME_INVALID,
|
||||
[0xBB] = QUIC_FRAME_INVALID,
|
||||
[0xBC] = QUIC_FRAME_INVALID,
|
||||
[0xBD] = QUIC_FRAME_INVALID,
|
||||
[0xBE] = QUIC_FRAME_INVALID,
|
||||
[0xBF] = QUIC_FRAME_INVALID,
|
||||
[0xC0] = QUIC_FRAME_INVALID,
|
||||
[0xC1] = QUIC_FRAME_INVALID,
|
||||
[0xC2] = QUIC_FRAME_INVALID,
|
||||
[0xC3] = QUIC_FRAME_INVALID,
|
||||
[0xC4] = QUIC_FRAME_INVALID,
|
||||
[0xC5] = QUIC_FRAME_INVALID,
|
||||
[0xC6] = QUIC_FRAME_INVALID,
|
||||
[0xC7] = QUIC_FRAME_INVALID,
|
||||
[0xC8] = QUIC_FRAME_INVALID,
|
||||
[0xC9] = QUIC_FRAME_INVALID,
|
||||
[0xCA] = QUIC_FRAME_INVALID,
|
||||
[0xCB] = QUIC_FRAME_INVALID,
|
||||
[0xCC] = QUIC_FRAME_INVALID,
|
||||
[0xCD] = QUIC_FRAME_INVALID,
|
||||
[0xCE] = QUIC_FRAME_INVALID,
|
||||
[0xCF] = QUIC_FRAME_INVALID,
|
||||
[0xD0] = QUIC_FRAME_INVALID,
|
||||
[0xD1] = QUIC_FRAME_INVALID,
|
||||
[0xD2] = QUIC_FRAME_INVALID,
|
||||
[0xD3] = QUIC_FRAME_INVALID,
|
||||
[0xD4] = QUIC_FRAME_INVALID,
|
||||
[0xD5] = QUIC_FRAME_INVALID,
|
||||
[0xD6] = QUIC_FRAME_INVALID,
|
||||
[0xD7] = QUIC_FRAME_INVALID,
|
||||
[0xD8] = QUIC_FRAME_INVALID,
|
||||
[0xD9] = QUIC_FRAME_INVALID,
|
||||
[0xDA] = QUIC_FRAME_INVALID,
|
||||
[0xDB] = QUIC_FRAME_INVALID,
|
||||
[0xDC] = QUIC_FRAME_INVALID,
|
||||
[0xDD] = QUIC_FRAME_INVALID,
|
||||
[0xDE] = QUIC_FRAME_INVALID,
|
||||
[0xDF] = QUIC_FRAME_INVALID,
|
||||
[0xE0] = QUIC_FRAME_INVALID,
|
||||
[0xE1] = QUIC_FRAME_INVALID,
|
||||
[0xE2] = QUIC_FRAME_INVALID,
|
||||
[0xE3] = QUIC_FRAME_INVALID,
|
||||
[0xE4] = QUIC_FRAME_INVALID,
|
||||
[0xE5] = QUIC_FRAME_INVALID,
|
||||
[0xE6] = QUIC_FRAME_INVALID,
|
||||
[0xE7] = QUIC_FRAME_INVALID,
|
||||
[0xE8] = QUIC_FRAME_INVALID,
|
||||
[0xE9] = QUIC_FRAME_INVALID,
|
||||
[0xEA] = QUIC_FRAME_INVALID,
|
||||
[0xEB] = QUIC_FRAME_INVALID,
|
||||
[0xEC] = QUIC_FRAME_INVALID,
|
||||
[0xED] = QUIC_FRAME_INVALID,
|
||||
[0xEE] = QUIC_FRAME_INVALID,
|
||||
[0xEF] = QUIC_FRAME_INVALID,
|
||||
[0xF0] = QUIC_FRAME_INVALID,
|
||||
[0xF1] = QUIC_FRAME_INVALID,
|
||||
[0xF2] = QUIC_FRAME_INVALID,
|
||||
[0xF3] = QUIC_FRAME_INVALID,
|
||||
[0xF4] = QUIC_FRAME_INVALID,
|
||||
[0xF5] = QUIC_FRAME_INVALID,
|
||||
[0xF6] = QUIC_FRAME_INVALID,
|
||||
[0xF7] = QUIC_FRAME_INVALID,
|
||||
[0xF8] = QUIC_FRAME_INVALID,
|
||||
[0xF9] = QUIC_FRAME_INVALID,
|
||||
[0xFA] = QUIC_FRAME_INVALID,
|
||||
[0xFB] = QUIC_FRAME_INVALID,
|
||||
[0xFC] = QUIC_FRAME_INVALID,
|
||||
[0xFD] = QUIC_FRAME_INVALID,
|
||||
[0xFE] = QUIC_FRAME_INVALID,
|
||||
[0xFF] = QUIC_FRAME_INVALID,
|
||||
};
|
||||
return byte2type[byte];
|
||||
|
||||
if (len > 1 && buf[0] < 0x40)
|
||||
return byte2type[buf[0]];
|
||||
else
|
||||
return QUIC_FRAME_INVALID;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1669,6 +1495,76 @@ ietf_v1_parse_two_varints (const unsigned char *buf, size_t len, uint64_t *vals[
|
|||
}
|
||||
|
||||
|
||||
/* vals[0] is the frame type */
|
||||
static unsigned
|
||||
ietf_v1_frame_with_varints_size (unsigned n, uint64_t vals[])
|
||||
{
|
||||
unsigned vbits, size;
|
||||
|
||||
assert(n > 0);
|
||||
vbits = vint_val2bits(vals[0]);
|
||||
size = 1 << vbits;
|
||||
while (--n)
|
||||
{
|
||||
vbits = vint_val2bits(vals[n]);
|
||||
size += 1 << vbits;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* vals[0] is the frame type */
|
||||
static int
|
||||
ietf_v1_gen_frame_with_varints (unsigned char *buf, size_t len,
|
||||
unsigned count, uint64_t vals[])
|
||||
{
|
||||
unsigned vbits, n;
|
||||
unsigned char *p;
|
||||
|
||||
if (ietf_v1_frame_with_varints_size(count, vals) > len)
|
||||
return -1;
|
||||
|
||||
p = buf;
|
||||
for (n = 0; n < count; ++n)
|
||||
{
|
||||
vbits = vint_val2bits(vals[n]);
|
||||
vint_write(p, vals[n], vbits, 1 << vbits);
|
||||
p += 1 << vbits;
|
||||
}
|
||||
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
|
||||
/* Frame type is checked when frame type is parsed. The only use here is
|
||||
* to calculate skip length.
|
||||
*/
|
||||
static int
|
||||
ietf_v1_parse_frame_with_varints (const unsigned char *buf, size_t len,
|
||||
const uint64_t frame_type, unsigned count, uint64_t *vals[])
|
||||
{
|
||||
const unsigned char *p = buf;
|
||||
const unsigned char *const end = p + len;
|
||||
unsigned vbits, n;
|
||||
int s;
|
||||
|
||||
vbits = vint_val2bits(frame_type);
|
||||
p += 1 << vbits;
|
||||
|
||||
for (n = 0; n < count; ++n)
|
||||
{
|
||||
s = vint_read(p, end, vals[n]);
|
||||
if (s < 0)
|
||||
return s;
|
||||
p += s;
|
||||
}
|
||||
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
ietf_v1_parse_stream_blocked_frame (const unsigned char *buf, size_t len,
|
||||
lsquic_stream_id_t *stream_id, uint64_t *offset)
|
||||
|
@ -2251,6 +2147,49 @@ ietf_v1_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_v1_gen_ack_frequency_frame (unsigned char *buf, size_t buf_len,
|
||||
uint64_t seqno, uint64_t pack_tol, uint64_t upd_mad)
|
||||
{
|
||||
return ietf_v1_gen_frame_with_varints(buf, buf_len, 4,
|
||||
(uint64_t[]){ 0xAF, seqno, pack_tol, upd_mad });
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_v1_parse_ack_frequency_frame (const unsigned char *buf, size_t buf_len,
|
||||
uint64_t *seqno, uint64_t *pack_tol, uint64_t *upd_mad)
|
||||
{
|
||||
return ietf_v1_parse_frame_with_varints(buf, buf_len,
|
||||
0xAF, 3, (uint64_t *[]) { seqno, pack_tol, upd_mad });
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_id24_gen_ack_frequency_frame (unsigned char *buf, size_t buf_len,
|
||||
uint64_t seqno, uint64_t pack_tol, uint64_t upd_mad)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_id24_parse_ack_frequency_frame (const unsigned char *buf, size_t buf_len,
|
||||
uint64_t *seqno, uint64_t *pack_tol, uint64_t *upd_mad)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
ietf_v1_ack_frequency_frame_size (uint64_t seqno, uint64_t pack_tol,
|
||||
uint64_t upd_mad)
|
||||
{
|
||||
return ietf_v1_frame_with_varints_size(4,
|
||||
(uint64_t[]){ 0xAF, seqno, pack_tol, upd_mad });
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
ietf_v1_handshake_done_frame_size (void)
|
||||
{
|
||||
|
@ -2339,6 +2278,9 @@ const struct parse_funcs lsquic_parse_funcs_ietf_id24 =
|
|||
.pf_gen_handshake_done_frame = ietf_id24_gen_handshake_done_frame,
|
||||
.pf_parse_handshake_done_frame = ietf_id24_parse_handshake_done_frame,
|
||||
.pf_handshake_done_frame_size = ietf_v1_handshake_done_frame_size,
|
||||
.pf_gen_ack_frequency_frame = ietf_id24_gen_ack_frequency_frame,
|
||||
.pf_parse_ack_frequency_frame = ietf_id24_parse_ack_frequency_frame,
|
||||
.pf_ack_frequency_frame_size = ietf_v1_ack_frequency_frame_size,
|
||||
};
|
||||
|
||||
|
||||
|
@ -2407,4 +2349,7 @@ const struct parse_funcs lsquic_parse_funcs_ietf_v1 =
|
|||
.pf_gen_handshake_done_frame = ietf_v1_gen_handshake_done_frame,
|
||||
.pf_parse_handshake_done_frame = ietf_v1_parse_handshake_done_frame,
|
||||
.pf_handshake_done_frame_size = ietf_v1_handshake_done_frame_size,
|
||||
.pf_gen_ack_frequency_frame = ietf_v1_gen_ack_frequency_frame,
|
||||
.pf_parse_ack_frequency_frame = ietf_v1_parse_ack_frequency_frame,
|
||||
.pf_ack_frequency_frame_size = ietf_v1_ack_frequency_frame_size,
|
||||
};
|
||||
|
|
|
@ -239,7 +239,7 @@ lsquic_is_valid_iquic_hs_packet (const unsigned char *buf, size_t length,
|
|||
}
|
||||
|
||||
|
||||
const enum quic_frame_type lsquic_iquic_byte2type[0x100] =
|
||||
const enum quic_frame_type lsquic_iquic_byte2type[0x40] =
|
||||
{
|
||||
[0x00] = QUIC_FRAME_PADDING,
|
||||
[0x01] = QUIC_FRAME_PING,
|
||||
|
@ -305,198 +305,6 @@ const enum quic_frame_type lsquic_iquic_byte2type[0x100] =
|
|||
[0x3D] = QUIC_FRAME_INVALID,
|
||||
[0x3E] = QUIC_FRAME_INVALID,
|
||||
[0x3F] = QUIC_FRAME_INVALID,
|
||||
[0x40] = QUIC_FRAME_INVALID,
|
||||
[0x41] = QUIC_FRAME_INVALID,
|
||||
[0x42] = QUIC_FRAME_INVALID,
|
||||
[0x43] = QUIC_FRAME_INVALID,
|
||||
[0x44] = QUIC_FRAME_INVALID,
|
||||
[0x45] = QUIC_FRAME_INVALID,
|
||||
[0x46] = QUIC_FRAME_INVALID,
|
||||
[0x47] = QUIC_FRAME_INVALID,
|
||||
[0x48] = QUIC_FRAME_INVALID,
|
||||
[0x49] = QUIC_FRAME_INVALID,
|
||||
[0x4A] = QUIC_FRAME_INVALID,
|
||||
[0x4B] = QUIC_FRAME_INVALID,
|
||||
[0x4C] = QUIC_FRAME_INVALID,
|
||||
[0x4D] = QUIC_FRAME_INVALID,
|
||||
[0x4E] = QUIC_FRAME_INVALID,
|
||||
[0x4F] = QUIC_FRAME_INVALID,
|
||||
[0x50] = QUIC_FRAME_INVALID,
|
||||
[0x51] = QUIC_FRAME_INVALID,
|
||||
[0x52] = QUIC_FRAME_INVALID,
|
||||
[0x53] = QUIC_FRAME_INVALID,
|
||||
[0x54] = QUIC_FRAME_INVALID,
|
||||
[0x55] = QUIC_FRAME_INVALID,
|
||||
[0x56] = QUIC_FRAME_INVALID,
|
||||
[0x57] = QUIC_FRAME_INVALID,
|
||||
[0x58] = QUIC_FRAME_INVALID,
|
||||
[0x59] = QUIC_FRAME_INVALID,
|
||||
[0x5A] = QUIC_FRAME_INVALID,
|
||||
[0x5B] = QUIC_FRAME_INVALID,
|
||||
[0x5C] = QUIC_FRAME_INVALID,
|
||||
[0x5D] = QUIC_FRAME_INVALID,
|
||||
[0x5E] = QUIC_FRAME_INVALID,
|
||||
[0x5F] = QUIC_FRAME_INVALID,
|
||||
[0x60] = QUIC_FRAME_INVALID,
|
||||
[0x61] = QUIC_FRAME_INVALID,
|
||||
[0x62] = QUIC_FRAME_INVALID,
|
||||
[0x63] = QUIC_FRAME_INVALID,
|
||||
[0x64] = QUIC_FRAME_INVALID,
|
||||
[0x65] = QUIC_FRAME_INVALID,
|
||||
[0x66] = QUIC_FRAME_INVALID,
|
||||
[0x67] = QUIC_FRAME_INVALID,
|
||||
[0x68] = QUIC_FRAME_INVALID,
|
||||
[0x69] = QUIC_FRAME_INVALID,
|
||||
[0x6A] = QUIC_FRAME_INVALID,
|
||||
[0x6B] = QUIC_FRAME_INVALID,
|
||||
[0x6C] = QUIC_FRAME_INVALID,
|
||||
[0x6D] = QUIC_FRAME_INVALID,
|
||||
[0x6E] = QUIC_FRAME_INVALID,
|
||||
[0x6F] = QUIC_FRAME_INVALID,
|
||||
[0x70] = QUIC_FRAME_INVALID,
|
||||
[0x71] = QUIC_FRAME_INVALID,
|
||||
[0x72] = QUIC_FRAME_INVALID,
|
||||
[0x73] = QUIC_FRAME_INVALID,
|
||||
[0x74] = QUIC_FRAME_INVALID,
|
||||
[0x75] = QUIC_FRAME_INVALID,
|
||||
[0x76] = QUIC_FRAME_INVALID,
|
||||
[0x77] = QUIC_FRAME_INVALID,
|
||||
[0x78] = QUIC_FRAME_INVALID,
|
||||
[0x79] = QUIC_FRAME_INVALID,
|
||||
[0x7A] = QUIC_FRAME_INVALID,
|
||||
[0x7B] = QUIC_FRAME_INVALID,
|
||||
[0x7C] = QUIC_FRAME_INVALID,
|
||||
[0x7D] = QUIC_FRAME_INVALID,
|
||||
[0x7E] = QUIC_FRAME_INVALID,
|
||||
[0x7F] = QUIC_FRAME_INVALID,
|
||||
[0x80] = QUIC_FRAME_INVALID,
|
||||
[0x81] = QUIC_FRAME_INVALID,
|
||||
[0x82] = QUIC_FRAME_INVALID,
|
||||
[0x83] = QUIC_FRAME_INVALID,
|
||||
[0x84] = QUIC_FRAME_INVALID,
|
||||
[0x85] = QUIC_FRAME_INVALID,
|
||||
[0x86] = QUIC_FRAME_INVALID,
|
||||
[0x87] = QUIC_FRAME_INVALID,
|
||||
[0x88] = QUIC_FRAME_INVALID,
|
||||
[0x89] = QUIC_FRAME_INVALID,
|
||||
[0x8A] = QUIC_FRAME_INVALID,
|
||||
[0x8B] = QUIC_FRAME_INVALID,
|
||||
[0x8C] = QUIC_FRAME_INVALID,
|
||||
[0x8D] = QUIC_FRAME_INVALID,
|
||||
[0x8E] = QUIC_FRAME_INVALID,
|
||||
[0x8F] = QUIC_FRAME_INVALID,
|
||||
[0x90] = QUIC_FRAME_INVALID,
|
||||
[0x91] = QUIC_FRAME_INVALID,
|
||||
[0x92] = QUIC_FRAME_INVALID,
|
||||
[0x93] = QUIC_FRAME_INVALID,
|
||||
[0x94] = QUIC_FRAME_INVALID,
|
||||
[0x95] = QUIC_FRAME_INVALID,
|
||||
[0x96] = QUIC_FRAME_INVALID,
|
||||
[0x97] = QUIC_FRAME_INVALID,
|
||||
[0x98] = QUIC_FRAME_INVALID,
|
||||
[0x99] = QUIC_FRAME_INVALID,
|
||||
[0x9A] = QUIC_FRAME_INVALID,
|
||||
[0x9B] = QUIC_FRAME_INVALID,
|
||||
[0x9C] = QUIC_FRAME_INVALID,
|
||||
[0x9D] = QUIC_FRAME_INVALID,
|
||||
[0x9E] = QUIC_FRAME_INVALID,
|
||||
[0x9F] = QUIC_FRAME_INVALID,
|
||||
[0xA0] = QUIC_FRAME_INVALID,
|
||||
[0xA1] = QUIC_FRAME_INVALID,
|
||||
[0xA2] = QUIC_FRAME_INVALID,
|
||||
[0xA3] = QUIC_FRAME_INVALID,
|
||||
[0xA4] = QUIC_FRAME_INVALID,
|
||||
[0xA5] = QUIC_FRAME_INVALID,
|
||||
[0xA6] = QUIC_FRAME_INVALID,
|
||||
[0xA7] = QUIC_FRAME_INVALID,
|
||||
[0xA8] = QUIC_FRAME_INVALID,
|
||||
[0xA9] = QUIC_FRAME_INVALID,
|
||||
[0xAA] = QUIC_FRAME_INVALID,
|
||||
[0xAB] = QUIC_FRAME_INVALID,
|
||||
[0xAC] = QUIC_FRAME_INVALID,
|
||||
[0xAD] = QUIC_FRAME_INVALID,
|
||||
[0xAE] = QUIC_FRAME_INVALID,
|
||||
[0xAF] = QUIC_FRAME_INVALID,
|
||||
[0xB0] = QUIC_FRAME_INVALID,
|
||||
[0xB1] = QUIC_FRAME_INVALID,
|
||||
[0xB2] = QUIC_FRAME_INVALID,
|
||||
[0xB3] = QUIC_FRAME_INVALID,
|
||||
[0xB4] = QUIC_FRAME_INVALID,
|
||||
[0xB5] = QUIC_FRAME_INVALID,
|
||||
[0xB6] = QUIC_FRAME_INVALID,
|
||||
[0xB7] = QUIC_FRAME_INVALID,
|
||||
[0xB8] = QUIC_FRAME_INVALID,
|
||||
[0xB9] = QUIC_FRAME_INVALID,
|
||||
[0xBA] = QUIC_FRAME_INVALID,
|
||||
[0xBB] = QUIC_FRAME_INVALID,
|
||||
[0xBC] = QUIC_FRAME_INVALID,
|
||||
[0xBD] = QUIC_FRAME_INVALID,
|
||||
[0xBE] = QUIC_FRAME_INVALID,
|
||||
[0xBF] = QUIC_FRAME_INVALID,
|
||||
[0xC0] = QUIC_FRAME_INVALID,
|
||||
[0xC1] = QUIC_FRAME_INVALID,
|
||||
[0xC2] = QUIC_FRAME_INVALID,
|
||||
[0xC3] = QUIC_FRAME_INVALID,
|
||||
[0xC4] = QUIC_FRAME_INVALID,
|
||||
[0xC5] = QUIC_FRAME_INVALID,
|
||||
[0xC6] = QUIC_FRAME_INVALID,
|
||||
[0xC7] = QUIC_FRAME_INVALID,
|
||||
[0xC8] = QUIC_FRAME_INVALID,
|
||||
[0xC9] = QUIC_FRAME_INVALID,
|
||||
[0xCA] = QUIC_FRAME_INVALID,
|
||||
[0xCB] = QUIC_FRAME_INVALID,
|
||||
[0xCC] = QUIC_FRAME_INVALID,
|
||||
[0xCD] = QUIC_FRAME_INVALID,
|
||||
[0xCE] = QUIC_FRAME_INVALID,
|
||||
[0xCF] = QUIC_FRAME_INVALID,
|
||||
[0xD0] = QUIC_FRAME_INVALID,
|
||||
[0xD1] = QUIC_FRAME_INVALID,
|
||||
[0xD2] = QUIC_FRAME_INVALID,
|
||||
[0xD3] = QUIC_FRAME_INVALID,
|
||||
[0xD4] = QUIC_FRAME_INVALID,
|
||||
[0xD5] = QUIC_FRAME_INVALID,
|
||||
[0xD6] = QUIC_FRAME_INVALID,
|
||||
[0xD7] = QUIC_FRAME_INVALID,
|
||||
[0xD8] = QUIC_FRAME_INVALID,
|
||||
[0xD9] = QUIC_FRAME_INVALID,
|
||||
[0xDA] = QUIC_FRAME_INVALID,
|
||||
[0xDB] = QUIC_FRAME_INVALID,
|
||||
[0xDC] = QUIC_FRAME_INVALID,
|
||||
[0xDD] = QUIC_FRAME_INVALID,
|
||||
[0xDE] = QUIC_FRAME_INVALID,
|
||||
[0xDF] = QUIC_FRAME_INVALID,
|
||||
[0xE0] = QUIC_FRAME_INVALID,
|
||||
[0xE1] = QUIC_FRAME_INVALID,
|
||||
[0xE2] = QUIC_FRAME_INVALID,
|
||||
[0xE3] = QUIC_FRAME_INVALID,
|
||||
[0xE4] = QUIC_FRAME_INVALID,
|
||||
[0xE5] = QUIC_FRAME_INVALID,
|
||||
[0xE6] = QUIC_FRAME_INVALID,
|
||||
[0xE7] = QUIC_FRAME_INVALID,
|
||||
[0xE8] = QUIC_FRAME_INVALID,
|
||||
[0xE9] = QUIC_FRAME_INVALID,
|
||||
[0xEA] = QUIC_FRAME_INVALID,
|
||||
[0xEB] = QUIC_FRAME_INVALID,
|
||||
[0xEC] = QUIC_FRAME_INVALID,
|
||||
[0xED] = QUIC_FRAME_INVALID,
|
||||
[0xEE] = QUIC_FRAME_INVALID,
|
||||
[0xEF] = QUIC_FRAME_INVALID,
|
||||
[0xF0] = QUIC_FRAME_INVALID,
|
||||
[0xF1] = QUIC_FRAME_INVALID,
|
||||
[0xF2] = QUIC_FRAME_INVALID,
|
||||
[0xF3] = QUIC_FRAME_INVALID,
|
||||
[0xF4] = QUIC_FRAME_INVALID,
|
||||
[0xF5] = QUIC_FRAME_INVALID,
|
||||
[0xF6] = QUIC_FRAME_INVALID,
|
||||
[0xF7] = QUIC_FRAME_INVALID,
|
||||
[0xF8] = QUIC_FRAME_INVALID,
|
||||
[0xF9] = QUIC_FRAME_INVALID,
|
||||
[0xFA] = QUIC_FRAME_INVALID,
|
||||
[0xFB] = QUIC_FRAME_INVALID,
|
||||
[0xFC] = QUIC_FRAME_INVALID,
|
||||
[0xFD] = QUIC_FRAME_INVALID,
|
||||
[0xFE] = QUIC_FRAME_INVALID,
|
||||
[0xFF] = QUIC_FRAME_INVALID,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -381,4 +381,6 @@ lsquic_send_ctl_cidlen_change (struct lsquic_send_ctl *,
|
|||
void
|
||||
lsquic_send_ctl_begin_optack_detection (struct lsquic_send_ctl *);
|
||||
|
||||
#define lsquic_send_ctl_n_unacked(ctl_) ((ctl_)->sc_n_in_flight_retx)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,6 +51,7 @@ tpi_val_2_enum (uint64_t tpi_val)
|
|||
case 0xC37: return TPI_QUANTUM_READINESS;
|
||||
#endif
|
||||
case 0x1057: return TPI_LOSS_BITS;
|
||||
case 0xDE1A: return TPI_MIN_ACK_DELAY;
|
||||
default: return INT_MAX;
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +78,7 @@ static const unsigned short enum_2_tpi_val[LAST_TPI + 1] =
|
|||
[TPI_QUANTUM_READINESS] = 0xC37,
|
||||
#endif
|
||||
[TPI_LOSS_BITS] = 0x1057,
|
||||
[TPI_MIN_ACK_DELAY] = 0xDE1A,
|
||||
};
|
||||
|
||||
|
||||
|
@ -101,6 +103,7 @@ static const char * const tpi2str[LAST_TPI + 1] =
|
|||
[TPI_QUANTUM_READINESS] = "quantum_readiness",
|
||||
#endif
|
||||
[TPI_LOSS_BITS] = "loss_bits",
|
||||
[TPI_MIN_ACK_DELAY] = "min_ack_delay",
|
||||
};
|
||||
|
||||
|
||||
|
@ -134,6 +137,13 @@ static const uint64_t max_vals[MAX_NUMERIC_TPI + 1] =
|
|||
[TPI_MAX_ACK_DELAY] = TP_MAX_MAX_ACK_DELAY,
|
||||
[TPI_ACTIVE_CONNECTION_ID_LIMIT] = VINT_MAX_VALUE,
|
||||
[TPI_LOSS_BITS] = 1,
|
||||
[TPI_MIN_ACK_DELAY] = (1u << 24) - 1u,
|
||||
};
|
||||
|
||||
|
||||
static const uint64_t min_vals[MAX_NUMERIC_TPI + 1] =
|
||||
{
|
||||
[TPI_MIN_ACK_DELAY] = 1,
|
||||
};
|
||||
|
||||
|
||||
|
@ -203,16 +213,24 @@ lsquic_tp_encode (const struct transport_params *params, int is_server,
|
|||
if (tpi > MAX_NUM_WITH_DEF_TPI
|
||||
|| params->tp_numerics[tpi] != def_vals[tpi])
|
||||
{
|
||||
if (params->tp_numerics[tpi] <= max_vals[tpi])
|
||||
if (params->tp_numerics[tpi] >= min_vals[tpi]
|
||||
&& params->tp_numerics[tpi] <= max_vals[tpi])
|
||||
{
|
||||
bits[tpi] = vint_val2bits(params->tp_numerics[tpi]);
|
||||
need += 4 + (1 << bits[tpi]);
|
||||
}
|
||||
else if (params->tp_numerics[tpi] > max_vals[tpi])
|
||||
{
|
||||
LSQ_DEBUG("numeric value of %s is too large (%"PRIu64" vs "
|
||||
"maximum of %"PRIu64")", tpi2str[tpi],
|
||||
params->tp_numerics[tpi], max_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("numeric value is too large (%"PRIu64" vs maximum "
|
||||
"of %"PRIu64")", params->tp_numerics[tpi],
|
||||
max_vals[tpi]);
|
||||
LSQ_DEBUG("numeric value of %s is too small (%"PRIu64" vs "
|
||||
"minimum " "of %"PRIu64")",
|
||||
tpi2str[tpi], params->tp_numerics[tpi], min_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -278,6 +296,7 @@ lsquic_tp_encode (const struct transport_params *params, int is_server,
|
|||
case TPI_MAX_ACK_DELAY:
|
||||
case TPI_ACTIVE_CONNECTION_ID_LIMIT:
|
||||
case TPI_LOSS_BITS:
|
||||
case TPI_MIN_ACK_DELAY:
|
||||
WRITE_UINT_TO_P(1 << bits[tpi], 16);
|
||||
vint_write(p, params->tp_numerics[tpi], bits[tpi],
|
||||
1 << bits[tpi]);
|
||||
|
@ -392,6 +411,7 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
|||
case TPI_MAX_ACK_DELAY:
|
||||
case TPI_ACTIVE_CONNECTION_ID_LIMIT:
|
||||
case TPI_LOSS_BITS:
|
||||
case TPI_MIN_ACK_DELAY:
|
||||
switch (len)
|
||||
{
|
||||
case 1:
|
||||
|
@ -403,9 +423,16 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
|||
{
|
||||
if (params->tp_numerics[tpi] > max_vals[tpi])
|
||||
{
|
||||
LSQ_DEBUG("numeric value of parameter 0x%X is too "
|
||||
"large (%"PRIu64" vs maximum of %"PRIu64,
|
||||
param_id, params->tp_numerics[tpi], max_vals[tpi]);
|
||||
LSQ_DEBUG("numeric value of %s is too large "
|
||||
"(%"PRIu64" vs maximum of %"PRIu64, tpi2str[tpi],
|
||||
params->tp_numerics[tpi], max_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
else if (params->tp_numerics[tpi] < min_vals[tpi])
|
||||
{
|
||||
LSQ_DEBUG("numeric value of %s is too small "
|
||||
"(%"PRIu64" vs minimum of %"PRIu64, tpi2str[tpi],
|
||||
params->tp_numerics[tpi], min_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
@ -502,6 +529,17 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
|||
if (p != end)
|
||||
return -1;
|
||||
|
||||
if ((params->tp_set & (1 << TPI_MIN_ACK_DELAY))
|
||||
&& params->tp_numerics[TPI_MIN_ACK_DELAY]
|
||||
> params->tp_numerics[TPI_MAX_ACK_DELAY] * 1000)
|
||||
{
|
||||
LSQ_DEBUG("min_ack_delay (%"PRIu64" usec) is larger than "
|
||||
"max_ack_delay (%"PRIu64" ms)",
|
||||
params->tp_numerics[TPI_MIN_ACK_DELAY],
|
||||
params->tp_numerics[TPI_MAX_ACK_DELAY]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) (end - buf);
|
||||
#undef EXPECT_LEN
|
||||
}
|
||||
|
@ -517,7 +555,7 @@ lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
|
|||
char addr_str[INET6_ADDRSTRLEN];
|
||||
|
||||
for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
|
||||
if (params->tp_set & (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL))
|
||||
if (params->tp_set & (1 << tpi))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "%.*s%s: %"PRIu64,
|
||||
(buf + sz > end) << 1, "; ", tpi2str[tpi],
|
||||
|
|
|
@ -32,6 +32,7 @@ enum transport_param_id
|
|||
/*
|
||||
* Numeric transport parameters without default values:
|
||||
*/
|
||||
TPI_MIN_ACK_DELAY,
|
||||
TPI_LOSS_BITS, MAX_NUMERIC_TPI = TPI_LOSS_BITS,
|
||||
|
||||
/*
|
||||
|
|
|
@ -1846,6 +1846,11 @@ set_engine_option (struct lsquic_engine_settings *settings,
|
|||
settings->es_handshake_to = atoi(val);
|
||||
return 0;
|
||||
}
|
||||
if (0 == strncmp(name, "delayed_acks", 12))
|
||||
{
|
||||
settings->es_delayed_acks = atoi(val);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
if (0 == strncmp(name, "support_tcid0", 13))
|
||||
|
|
Loading…
Reference in a new issue