mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.10.0
- [FEATURE] QUIC and HTTP/3 Internet Draft 25 support. - [API] Drop support for ID-23. - [BUGFIX] Set key phase bit on outgoing packets correctly. - Code cleanup.
This commit is contained in:
parent
fb96f4dd43
commit
9fc120419d
51 changed files with 8220 additions and 258 deletions
|
@ -1,3 +1,10 @@
|
|||
2020-01-28
|
||||
- 2.10.0
|
||||
- [FEATURE] QUIC and HTTP/3 Internet Draft 25 support.
|
||||
- [API] Drop support for ID-23.
|
||||
- [BUGFIX] Set key phase bit on outgoing packets correctly.
|
||||
- Code cleanup.
|
||||
|
||||
2020-01-20
|
||||
- 2.9.0
|
||||
- [API] Drop support for Q039.
|
||||
|
|
|
@ -15,7 +15,7 @@ and OpenLiteSpeed. We think it is free of major problems. Nevertheless, do
|
|||
not hesitate to report bugs back to us. Even better, send us fixes and
|
||||
improvements!
|
||||
|
||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-23, and ID-24.
|
||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-24, and ID-25.
|
||||
Support for newer versions will be added soon after they are released.
|
||||
|
||||
Documentation
|
||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define LSQUIC_MAJOR_VERSION 2
|
||||
#define LSQUIC_MINOR_VERSION 9
|
||||
#define LSQUIC_MINOR_VERSION 10
|
||||
#define LSQUIC_PATCH_VERSION 0
|
||||
|
||||
/**
|
||||
|
@ -133,16 +133,16 @@ enum lsquic_version
|
|||
#define LSQUIC_EXPERIMENTAL_Q098 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IETF QUIC Draft-23
|
||||
*/
|
||||
LSQVER_ID23,
|
||||
|
||||
/**
|
||||
* IETF QUIC Draft-24
|
||||
*/
|
||||
LSQVER_ID24,
|
||||
|
||||
/**
|
||||
* IETF QUIC Draft-25
|
||||
*/
|
||||
LSQVER_ID25,
|
||||
|
||||
/**
|
||||
* Special version to trigger version negotiation.
|
||||
* [draft-ietf-quic-transport-11], Section 3.
|
||||
|
@ -153,7 +153,7 @@ enum lsquic_version
|
|||
};
|
||||
|
||||
/**
|
||||
* We currently support versions 43, 46, 50, and IETF Draft-23 and Draft-24
|
||||
* We currently support versions 43, 46, 50, and Draft-24
|
||||
* @see lsquic_version
|
||||
*/
|
||||
#define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1)
|
||||
|
@ -170,10 +170,10 @@ enum lsquic_version
|
|||
|
||||
#define LSQUIC_GQUIC_HEADER_VERSIONS (1 << LSQVER_043)
|
||||
|
||||
#define LSQUIC_IETF_VERSIONS ((1 << LSQVER_ID23) | (1 << LSQVER_ID24) \
|
||||
#define LSQUIC_IETF_VERSIONS ((1 << LSQVER_ID24) | (1 << LSQVER_ID25) \
|
||||
| (1 << LSQVER_VERNEG))
|
||||
|
||||
#define LSQUIC_IETF_DRAFT_VERSIONS ((1 << LSQVER_ID23) | (1 << LSQVER_ID24) \
|
||||
#define LSQUIC_IETF_DRAFT_VERSIONS ((1 << LSQVER_ID24) | (1 << LSQVER_ID25) \
|
||||
| (1 << LSQVER_VERNEG))
|
||||
|
||||
enum lsquic_hsk_status
|
||||
|
|
|
@ -26,6 +26,7 @@ SET(lsquic_STAT_SRCS
|
|||
lsquic_frame_reader.c
|
||||
lsquic_frame_writer.c
|
||||
lsquic_full_conn.c
|
||||
lsquic_full_conn_id24.c
|
||||
lsquic_full_conn_ietf.c
|
||||
lsquic_global.c
|
||||
lsquic_handshake.c
|
||||
|
|
|
@ -31,6 +31,7 @@ liblsquic_a_SOURCES = ls-qpack/lsqpack.c \
|
|||
lsquic_frame_reader.c \
|
||||
lsquic_frame_writer.c \
|
||||
lsquic_full_conn.c \
|
||||
lsquic_full_conn_id24.c \
|
||||
lsquic_full_conn_ietf.c \
|
||||
lsquic_global.c \
|
||||
lsquic_handshake.c \
|
||||
|
|
|
@ -48,6 +48,7 @@ const char *const lsquic_alid2str[] =
|
|||
[AL_PATH_CHAL_0] = "PATH_CHAL_0",
|
||||
[AL_PATH_CHAL_1] = "PATH_CHAL_1",
|
||||
[AL_SESS_TICKET] = "SESS_TICKET",
|
||||
[AL_BLOCKED_KA] = "BLOCKED_KA",
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ enum alarm_id {
|
|||
AL_PATH_CHAL_0 = AL_PATH_CHAL,
|
||||
AL_PATH_CHAL_1,
|
||||
AL_SESS_TICKET,
|
||||
AL_BLOCKED_KA, /* Blocked Keep-Alive */
|
||||
MAX_LSQUIC_ALARMS
|
||||
};
|
||||
|
||||
|
@ -55,6 +56,7 @@ enum alarm_id_bit {
|
|||
ALBIT_PATH_CHAL_0 = 1 << AL_PATH_CHAL_0,
|
||||
ALBIT_PATH_CHAL_1 = 1 << AL_PATH_CHAL_1,
|
||||
ALBIT_SESS_TICKET = 1 << AL_SESS_TICKET,
|
||||
ALBIT_BLOCKED_KA = 1 << AL_BLOCKED_KA,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -164,14 +164,8 @@ set_startup_values (struct lsquic_bbr *bbr)
|
|||
|
||||
|
||||
static void
|
||||
lsquic_bbr_init (void *cong_ctl, const struct lsquic_conn_public *conn_pub,
|
||||
enum quic_ft_bit retx_frames)
|
||||
init_bbr (struct lsquic_bbr *bbr)
|
||||
{
|
||||
struct lsquic_bbr *const bbr = cong_ctl;
|
||||
bbr->bbr_conn_pub = conn_pub;
|
||||
lsquic_bw_sampler_init(&bbr->bbr_bw_sampler, conn_pub->lconn, retx_frames);
|
||||
|
||||
bbr->bbr_rtt_stats = &conn_pub->rtt_stats;
|
||||
bbr->bbr_mode = BBR_MODE_STARTUP;
|
||||
bbr->bbr_round_count = 0;
|
||||
minmax_init(&bbr->bbr_max_bandwidth, 10);
|
||||
|
@ -203,13 +197,36 @@ lsquic_bbr_init (void *cong_ctl, const struct lsquic_conn_public *conn_pub,
|
|||
bbr->bbr_flags &= ~BBR_FLAG_LAST_SAMPLE_APP_LIMITED;
|
||||
bbr->bbr_flags &= ~BBR_FLAG_HAS_NON_APP_LIMITED;
|
||||
bbr->bbr_flags &= ~BBR_FLAG_FLEXIBLE_APP_LIMITED;
|
||||
|
||||
set_startup_values(bbr);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lsquic_bbr_init (void *cong_ctl, const struct lsquic_conn_public *conn_pub,
|
||||
enum quic_ft_bit retx_frames)
|
||||
{
|
||||
struct lsquic_bbr *const bbr = cong_ctl;
|
||||
bbr->bbr_conn_pub = conn_pub;
|
||||
lsquic_bw_sampler_init(&bbr->bbr_bw_sampler, conn_pub->lconn, retx_frames);
|
||||
bbr->bbr_rtt_stats = &conn_pub->rtt_stats;
|
||||
|
||||
init_bbr(bbr);
|
||||
|
||||
LSQ_DEBUG("initialized");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lsquic_bbr_reinit (void *cong_ctl)
|
||||
{
|
||||
struct lsquic_bbr *const bbr = cong_ctl;
|
||||
|
||||
init_bbr(bbr);
|
||||
|
||||
LSQ_DEBUG("re-initialized");
|
||||
}
|
||||
|
||||
|
||||
static lsquic_time_t
|
||||
get_min_rtt (const struct lsquic_bbr *bbr)
|
||||
{
|
||||
|
@ -1060,6 +1077,7 @@ const struct cong_ctl_if lsquic_cong_bbr_if =
|
|||
.cci_pacing_rate = lsquic_bbr_pacing_rate,
|
||||
.cci_loss = lsquic_bbr_loss,
|
||||
.cci_lost = lsquic_bbr_lost,
|
||||
.cci_reinit = lsquic_bbr_reinit,
|
||||
.cci_timeout = lsquic_bbr_timeout,
|
||||
.cci_sent = lsquic_bbr_sent,
|
||||
.cci_was_quiet = lsquic_bbr_was_quiet,
|
||||
|
|
|
@ -23,6 +23,9 @@ struct cong_ctl_if
|
|||
(*cci_init) (void *cong_ctl, const struct lsquic_conn_public *,
|
||||
enum quic_ft_bit);
|
||||
|
||||
void
|
||||
(*cci_reinit) (void *cong_ctl);
|
||||
|
||||
void
|
||||
(*cci_ack) (void *cong_ctl, struct lsquic_packet_out *, unsigned packet_sz,
|
||||
lsquic_time_t now, int app_limited);
|
||||
|
|
|
@ -137,6 +137,16 @@ lsquic_cubic_init (void *cong_ctl, const struct lsquic_conn_public *conn_pub,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
lsquic_cubic_reinit (void *cong_ctl)
|
||||
{
|
||||
struct lsquic_cubic *const cubic = cong_ctl;
|
||||
cubic_reset(cubic);
|
||||
cubic->cu_ssthresh = 10000 * TCP_MSS; /* Emulate "unbounded" slow start */
|
||||
LSQ_DEBUG("re-initialized");
|
||||
}
|
||||
|
||||
|
||||
#define LOG_CWND(c) do { \
|
||||
if (LSQ_LOG_ENABLED(LSQ_LOG_INFO)) { \
|
||||
lsquic_time_t now = lsquic_time_now(); \
|
||||
|
@ -278,6 +288,7 @@ const struct cong_ctl_if lsquic_cong_cubic_if =
|
|||
.cci_init = lsquic_cubic_init,
|
||||
.cci_pacing_rate = lsquic_cubic_pacing_rate,
|
||||
.cci_loss = lsquic_cubic_loss,
|
||||
.cci_reinit = lsquic_cubic_reinit,
|
||||
.cci_timeout = lsquic_cubic_timeout,
|
||||
.cci_was_quiet = lsquic_cubic_was_quiet,
|
||||
};
|
||||
|
|
|
@ -295,7 +295,7 @@ struct enc_session_funcs_iquic
|
|||
const char *);
|
||||
|
||||
void
|
||||
(*esfi_1rtt_acked)(enc_session_t *);
|
||||
(*esfi_handshake_confirmed)(enc_session_t *);
|
||||
};
|
||||
|
||||
extern
|
||||
|
@ -321,8 +321,8 @@ struct enc_session_funcs_gquic lsquic_enc_session_gquic_gquic_1;
|
|||
extern const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1;
|
||||
|
||||
#define select_esf_common_by_ver(ver) ( \
|
||||
ver == LSQVER_ID23 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||
ver == LSQVER_ID24 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||
ver == LSQVER_ID25 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||
ver == LSQVER_VERNEG ? &lsquic_enc_session_common_ietf_v1 : \
|
||||
ver == LSQVER_050 ? &lsquic_enc_session_common_gquic_2 : \
|
||||
&lsquic_enc_session_common_gquic_1 )
|
||||
|
|
|
@ -74,8 +74,8 @@ static const struct alpn_map {
|
|||
const unsigned char *alpn;
|
||||
} s_alpns[] = {
|
||||
{ LSQVER_ID24, (unsigned char *) "\x05h3-24", },
|
||||
{ LSQVER_ID23, (unsigned char *) "\x05h3-23", },
|
||||
{ LSQVER_VERNEG, (unsigned char *) "\x05h3-24", },
|
||||
{ LSQVER_ID25, (unsigned char *) "\x05h3-25", },
|
||||
{ LSQVER_VERNEG, (unsigned char *) "\x05h3-25", },
|
||||
};
|
||||
|
||||
struct enc_sess_iquic;
|
||||
|
@ -235,7 +235,7 @@ struct enc_sess_iquic
|
|||
ESI_HAVE_PEER_TP = 1 << 7,
|
||||
ESI_ALPN_CHECKED = 1 << 8,
|
||||
ESI_CACHED_INFO = 1 << 9,
|
||||
ESI_1RTT_ACKED = 1 << 10,
|
||||
ESI_HSK_CONFIRMED= 1 << 10,
|
||||
ESI_WANT_TICKET = 1 << 11,
|
||||
ESI_RECV_QL_BITS = 1 << 12,
|
||||
ESI_SEND_QL_BITS = 1 << 13,
|
||||
|
@ -533,12 +533,16 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
= settings->es_init_max_streams_bidi;
|
||||
params.tp_ack_delay_exponent
|
||||
= TP_DEF_ACK_DELAY_EXP;
|
||||
params.tp_idle_timeout = settings->es_idle_timeout * 1000;
|
||||
params.tp_max_idle_timeout = settings->es_idle_timeout * 1000;
|
||||
params.tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY;
|
||||
params.tp_max_packet_size = 1370 /* XXX: based on socket */;
|
||||
params.tp_active_connection_id_limit = MAX_IETF_CONN_DCIDS
|
||||
params.tp_active_connection_id_limit = MAX_IETF_CONN_DCIDS;
|
||||
if (enc_sess->esi_conn->cn_version == LSQVER_ID24)
|
||||
{
|
||||
params.tp_active_connection_id_limit = params.tp_active_connection_id_limit
|
||||
- 1 /* One slot is used by peer's SCID */
|
||||
- !!(params.tp_flags & (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6));
|
||||
}
|
||||
if (!settings->es_allow_migration)
|
||||
params.tp_disable_active_migration = 1;
|
||||
if (settings->es_ql_bits == -1)
|
||||
|
@ -1828,10 +1832,7 @@ static struct ku_label
|
|||
|
||||
select_ku_label (const struct enc_sess_iquic *enc_sess)
|
||||
{
|
||||
if (enc_sess->esi_conn->cn_version == LSQVER_ID23)
|
||||
return (struct ku_label) { "traffic upd", 11, };
|
||||
else
|
||||
return (struct ku_label) { "quic ku", 7, };
|
||||
return (struct ku_label) { "quic ku", 7, };
|
||||
}
|
||||
|
||||
|
||||
|
@ -2226,14 +2227,14 @@ iquic_esfi_reset_dcid (enc_session_t *enc_session_p,
|
|||
|
||||
|
||||
static void
|
||||
iquic_esfi_1rtt_acked (enc_session_t *sess)
|
||||
iquic_esfi_handshake_confirmed (enc_session_t *sess)
|
||||
{
|
||||
struct enc_sess_iquic *enc_sess = (struct enc_sess_iquic *) sess;
|
||||
|
||||
if (!(enc_sess->esi_flags & ESI_1RTT_ACKED))
|
||||
if (!(enc_sess->esi_flags & ESI_HSK_CONFIRMED))
|
||||
{
|
||||
LSQ_DEBUG("1RTT packet has been acked");
|
||||
enc_sess->esi_flags |= ESI_1RTT_ACKED;
|
||||
LSQ_DEBUG("handshake has been confirmed");
|
||||
enc_sess->esi_flags |= ESI_HSK_CONFIRMED;
|
||||
maybe_drop_SSL(enc_sess);
|
||||
}
|
||||
}
|
||||
|
@ -2254,7 +2255,8 @@ const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1 =
|
|||
.esfi_set_streams = iquic_esfi_set_streams,
|
||||
.esfi_create_server = iquic_esfi_create_server,
|
||||
.esfi_shake_stream = iquic_esfi_shake_stream,
|
||||
.esfi_1rtt_acked = iquic_esfi_1rtt_acked,
|
||||
.esfi_handshake_confirmed
|
||||
= iquic_esfi_handshake_confirmed,
|
||||
};
|
||||
|
||||
|
||||
|
@ -2310,8 +2312,8 @@ maybe_drop_SSL (struct enc_sess_iquic *enc_sess)
|
|||
* in which case we can close it, or (unlikely) they are buffered in the
|
||||
* frab list.
|
||||
*/
|
||||
if ((enc_sess->esi_flags & (ESI_1RTT_ACKED|ESI_HANDSHAKE_OK))
|
||||
== (ESI_1RTT_ACKED|ESI_HANDSHAKE_OK)
|
||||
if ((enc_sess->esi_flags & (ESI_HSK_CONFIRMED|ESI_HANDSHAKE_OK))
|
||||
== (ESI_HSK_CONFIRMED|ESI_HANDSHAKE_OK)
|
||||
&& enc_sess->esi_ssl
|
||||
&& lsquic_frab_list_empty(&enc_sess->esi_frals[ENC_LEV_FORW]))
|
||||
{
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
#include "lsquic_parse_common.h"
|
||||
#include "lsquic_handshake.h"
|
||||
#include "lsquic_crand.h"
|
||||
#include "lsquic_ietf.h"
|
||||
|
||||
#define LSQUIC_LOGGER_MODULE LSQLM_ENGINE
|
||||
#include "lsquic_logger.h"
|
||||
|
@ -259,6 +260,7 @@ struct lsquic_engine
|
|||
int last_tick_diff;
|
||||
#endif
|
||||
struct crand crand;
|
||||
EVP_AEAD_CTX retry_aead_ctx;
|
||||
};
|
||||
|
||||
|
||||
|
@ -625,6 +627,14 @@ lsquic_engine_new (unsigned flags,
|
|||
#if LSQUIC_CONN_STATS
|
||||
engine->stats_fh = api->ea_stats_fh;
|
||||
#endif
|
||||
if (1 != EVP_AEAD_CTX_init(&engine->retry_aead_ctx, EVP_aead_aes_128_gcm(),
|
||||
IETF_RETRY_KEY_BUF, IETF_RETRY_KEY_SZ, 16, NULL))
|
||||
{
|
||||
LSQ_ERROR("could not initialize retry AEAD ctx");
|
||||
lsquic_engine_destroy(engine);
|
||||
return NULL;
|
||||
}
|
||||
engine->pub.enp_retry_aead_ctx = &engine->retry_aead_ctx;
|
||||
|
||||
LSQ_INFO("instantiated engine");
|
||||
return engine;
|
||||
|
@ -878,7 +888,12 @@ new_full_conn_server (lsquic_engine_t *engine, lsquic_conn_t *mini_conn,
|
|||
flags = engine->flags & (ENG_SERVER|ENG_HTTP);
|
||||
|
||||
if (mini_conn->cn_flags & LSCONN_IETF)
|
||||
ctor = lsquic_ietf_full_conn_server_new;
|
||||
{
|
||||
if (mini_conn->cn_version == LSQVER_ID24)
|
||||
ctor = lsquic_id24_full_conn_server_new;
|
||||
else
|
||||
ctor = lsquic_ietf_full_conn_server_new;
|
||||
}
|
||||
else
|
||||
ctor = lsquic_gquic_full_conn_server_new;
|
||||
|
||||
|
@ -1434,6 +1449,8 @@ lsquic_engine_destroy (lsquic_engine_t *engine)
|
|||
#if LSQUIC_COUNT_ENGINE_CALLS
|
||||
LSQ_NOTICE("number of calls into the engine: %lu", engine->n_engine_calls);
|
||||
#endif
|
||||
if (engine->pub.enp_retry_aead_ctx)
|
||||
EVP_AEAD_CTX_cleanup(engine->pub.enp_retry_aead_ctx);
|
||||
free(engine);
|
||||
}
|
||||
|
||||
|
@ -1533,9 +1550,16 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version,
|
|||
else
|
||||
versions = 1u << version;
|
||||
if (versions & LSQUIC_IETF_VERSIONS)
|
||||
conn = lsquic_ietf_full_conn_client_new(&engine->pub, versions,
|
||||
flags, hostname, max_packet_size,
|
||||
is_ipv4, zero_rtt, zero_rtt_len, token, token_sz);
|
||||
{
|
||||
if (version == LSQVER_ID24)
|
||||
conn = lsquic_id24_full_conn_client_new(&engine->pub, versions,
|
||||
flags, hostname, max_packet_size,
|
||||
is_ipv4, zero_rtt, zero_rtt_len, token, token_sz);
|
||||
else
|
||||
conn = lsquic_ietf_full_conn_client_new(&engine->pub, versions,
|
||||
flags, hostname, max_packet_size,
|
||||
is_ipv4, zero_rtt, zero_rtt_len, token, token_sz);
|
||||
}
|
||||
else
|
||||
conn = lsquic_gquic_full_conn_client_new(&engine->pub, versions,
|
||||
flags, hostname, max_packet_size, is_ipv4,
|
||||
|
@ -2577,7 +2601,11 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
|||
engine_incref_conn(conn, LSCONN_ATTQ);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
/* In all other cases, the idle timeout would make the next
|
||||
* tick time non-zero:
|
||||
*/
|
||||
assert((conn->cn_flags & LSCONN_IETF)
|
||||
&& engine->pub.enp_settings.es_idle_timeout == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ struct lsquic_hash;
|
|||
struct lsquic_stream_if;
|
||||
struct ssl_ctx_st;
|
||||
struct crand;
|
||||
struct evp_aead_ctx_st;
|
||||
|
||||
enum warning_type
|
||||
{
|
||||
|
@ -62,6 +63,7 @@ struct lsquic_engine_public {
|
|||
unsigned char enp_ver_tags_buf[ sizeof(lsquic_ver_tag_t) * N_LSQVER ];
|
||||
unsigned enp_ver_tags_len;
|
||||
struct crand *enp_crand;
|
||||
struct evp_aead_ctx_st *enp_retry_aead_ctx;
|
||||
};
|
||||
|
||||
/* Put connection onto the Tickable Queue if it is not already on it. If
|
||||
|
|
|
@ -21,6 +21,14 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *,
|
|||
const unsigned char *zero_rtt, size_t,
|
||||
const unsigned char *token, size_t);
|
||||
|
||||
struct lsquic_conn *
|
||||
lsquic_id24_full_conn_client_new (struct lsquic_engine_public *,
|
||||
unsigned versions,
|
||||
unsigned flags /* Only FC_SERVER and FC_HTTP */,
|
||||
const char *hostname, unsigned short max_packet_size, int is_ipv4,
|
||||
const unsigned char *zero_rtt, size_t,
|
||||
const unsigned char *token, size_t);
|
||||
|
||||
typedef struct lsquic_conn *
|
||||
(*server_conn_ctor_f) (struct lsquic_engine_public *,
|
||||
unsigned flags /* Only FC_SERVER and FC_HTTP */,
|
||||
|
@ -36,6 +44,11 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *,
|
|||
unsigned flags /* Only FC_SERVER and FC_HTTP */,
|
||||
struct lsquic_conn *mini_conn);
|
||||
|
||||
struct lsquic_conn *
|
||||
lsquic_id24_full_conn_server_new (struct lsquic_engine_public *,
|
||||
unsigned flags /* Only FC_SERVER and FC_HTTP */,
|
||||
struct lsquic_conn *mini_conn);
|
||||
|
||||
struct dcid_elem
|
||||
{
|
||||
/* This is never both in the hash and on the retirement list */
|
||||
|
|
7108
src/liblsquic/lsquic_full_conn_id24.c
Normal file
7108
src/liblsquic/lsquic_full_conn_id24.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -12,6 +12,7 @@
|
|||
#include <string.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "fiu-local.h"
|
||||
|
@ -129,6 +130,7 @@ enum ifull_conn_flags
|
|||
IFC_FIRST_TICK = 1 << 24,
|
||||
IFC_IGNORE_HSK = 1 << 25,
|
||||
IFC_PROC_CRYPTO = 1 << 26,
|
||||
IFC_MIGRA = 1 << 27,
|
||||
};
|
||||
|
||||
|
||||
|
@ -353,12 +355,10 @@ struct ietf_full_conn
|
|||
unsigned char ifc_cur_path_id; /* Indexes ifc_paths */
|
||||
unsigned char ifc_used_paths; /* Bitmask */
|
||||
unsigned char ifc_mig_path_id;
|
||||
unsigned char ifc_original_cids;
|
||||
/* ifc_active_cids_limit is the maximum number of CIDs at any one time this
|
||||
* endpoint is allowed to issue to peer. If the TP value exceeds cn_n_cces,
|
||||
* it is reduced to it. ifc_active_cids_count tracks how many CIDs have
|
||||
* been issued. It is decremented each time a CID is retired. Both are
|
||||
* only applicable to CIDs issued via NEW_CONNECTION_ID frame.
|
||||
* been issued. It is decremented each time a CID is retired.
|
||||
*/
|
||||
unsigned char ifc_active_cids_limit;
|
||||
unsigned char ifc_active_cids_count;
|
||||
|
@ -388,9 +388,6 @@ struct ietf_full_conn
|
|||
} ifser_flags;
|
||||
} ser;
|
||||
} ifc_u;
|
||||
/* XXX This is 16 bytes per connection, which is expensive. Perhaps move
|
||||
* these to enpub (add a new IETF-specific section)?
|
||||
*/
|
||||
lsquic_time_t ifc_idle_to;
|
||||
lsquic_time_t ifc_ping_period;
|
||||
uint64_t ifc_last_max_data_off_sent;
|
||||
|
@ -564,6 +561,45 @@ path_chal_1_alarm_expired (enum alarm_id al_id, void *ctx,
|
|||
}
|
||||
|
||||
|
||||
/* Sending DATA_BLOCKED and STREAM_DATA_BLOCKED frames is a way to elicit
|
||||
* incoming packets from peer when it is too slow to read data. This is
|
||||
* recommended by [draft-ietf-quic-transport-25] Section 4.1.
|
||||
*
|
||||
* If we are still in the blocked state, we schedule a blocked frame to
|
||||
* be sent.
|
||||
*/
|
||||
static void
|
||||
blocked_ka_alarm_expired (enum alarm_id al_id, void *ctx,
|
||||
lsquic_time_t expiry, lsquic_time_t now)
|
||||
{
|
||||
struct ietf_full_conn *const conn = (struct ietf_full_conn *) ctx;
|
||||
struct lsquic_stream *stream;
|
||||
struct lsquic_hash_elem *el;
|
||||
|
||||
if (lsquic_conn_cap_avail(&conn->ifc_pub.conn_cap) == 0)
|
||||
{
|
||||
LSQ_DEBUG("set SEND_BLOCKED flag on connection");
|
||||
conn->ifc_conn.cn_flags |= LSCONN_SEND_BLOCKED;
|
||||
return;
|
||||
}
|
||||
|
||||
for (el = lsquic_hash_first(conn->ifc_pub.all_streams); el;
|
||||
el = lsquic_hash_next(conn->ifc_pub.all_streams))
|
||||
{
|
||||
stream = lsquic_hashelem_getdata(el);
|
||||
if (lsquic_stream_is_blocked(stream))
|
||||
{
|
||||
if (!(stream->sm_qflags & SMQF_SENDING_FLAGS))
|
||||
TAILQ_INSERT_TAIL(&conn->ifc_pub.sending_streams, stream,
|
||||
next_send_stream);
|
||||
stream->sm_qflags |= SMQF_SEND_BLOCKED;
|
||||
LSQ_DEBUG("set SEND_BLOCKED flag on stream %"PRIu64, stream->id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
migra_is_on (const struct ietf_full_conn *conn)
|
||||
{
|
||||
|
@ -612,6 +648,53 @@ ping_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry,
|
|||
static void
|
||||
retire_cid (struct ietf_full_conn *, struct conn_cid_elem *, lsquic_time_t);
|
||||
|
||||
|
||||
static void
|
||||
log_scids (const struct ietf_full_conn *conn)
|
||||
{
|
||||
const struct lsquic_conn *const lconn = &conn->ifc_conn;
|
||||
const struct conn_cid_elem *cce;
|
||||
char flags[5];
|
||||
unsigned idx;
|
||||
int fi;
|
||||
|
||||
LSQ_DEBUG("Log SCID array: (n_cces %hhu; mask: 0x%hhX; "
|
||||
"active: %hhu; limit: %hhu)",
|
||||
conn->ifc_conn.cn_n_cces, conn->ifc_conn.cn_cces_mask,
|
||||
conn->ifc_active_cids_count, conn->ifc_active_cids_limit);
|
||||
for (cce = lconn->cn_cces; cce < END_OF_CCES(lconn); ++cce)
|
||||
{
|
||||
idx = cce - lconn->cn_cces;
|
||||
fi = 0;
|
||||
if (cce->cce_flags & CCE_PORT) flags[fi++] = 'p';
|
||||
if (cce->cce_flags & CCE_REG) flags[fi++] = 'r';
|
||||
if (cce->cce_flags & CCE_SEQNO) flags[fi++] = 's';
|
||||
if (cce->cce_flags & CCE_USED) flags[fi++] = 'u';
|
||||
flags[fi] = '\0';
|
||||
if (lconn->cn_cces_mask & (1 << idx))
|
||||
{
|
||||
if (cce->cce_flags & CCE_PORT)
|
||||
LSQ_DEBUG( " %u: flags %-4s; port %hu", idx, flags,
|
||||
cce->cce_port);
|
||||
else if (cce->cce_flags & CCE_SEQNO)
|
||||
LSQ_DEBUGC(" %u: flags %-4s; seqno: %u; %"CID_FMT, idx,
|
||||
flags, cce->cce_seqno, CID_BITS(&cce->cce_cid));
|
||||
else
|
||||
LSQ_DEBUGC(" %u: flags %-4s; %"CID_FMT, idx, flags,
|
||||
CID_BITS(&cce->cce_cid));
|
||||
}
|
||||
else
|
||||
LSQ_DEBUG( " %u: flags %-4s; <empty>", idx, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define LOG_SCIDS(conn_) do { \
|
||||
if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG)) \
|
||||
log_scids(conn_); \
|
||||
} while (0)
|
||||
|
||||
|
||||
static void
|
||||
ret_cids_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry,
|
||||
lsquic_time_t now)
|
||||
|
@ -626,14 +709,14 @@ ret_cids_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry,
|
|||
for (cce = lconn->cn_cces; cce < END_OF_CCES(lconn); ++cce)
|
||||
{
|
||||
idx = cce - lconn->cn_cces;
|
||||
if (conn->ifc_original_cids & (1 << idx))
|
||||
if ((lconn->cn_cces_mask & (1 << idx))
|
||||
&& (cce->cce_flags & (CCE_SEQNO|CCE_PORT)) == 0)
|
||||
{
|
||||
assert(lconn->cn_cces_mask & (1 << idx));
|
||||
conn->ifc_original_cids &= ~(1 << idx);
|
||||
LSQ_DEBUG("retiring original CID at index %u", idx);
|
||||
retire_cid(conn, cce, now);
|
||||
}
|
||||
}
|
||||
LOG_SCIDS(conn);
|
||||
}
|
||||
|
||||
|
||||
|
@ -875,6 +958,7 @@ ietf_full_conn_add_scid (struct ietf_full_conn *conn,
|
|||
cce->cce_seqno = conn->ifc_scid_seqno++;
|
||||
cce->cce_flags |= CCE_SEQNO | flags;
|
||||
lconn->cn_cces_mask |= 1 << (cce - lconn->cn_cces);
|
||||
++conn->ifc_active_cids_count;
|
||||
if (enpub->enp_settings.es_scid_iss_rate)
|
||||
{
|
||||
min_timestamp = &conn->ifc_scid_timestamp[0];
|
||||
|
@ -923,6 +1007,7 @@ ietf_full_conn_init (struct ietf_full_conn *conn,
|
|||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_CID_THROT, cid_throt_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PATH_CHAL_0, path_chal_0_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PATH_CHAL_1, path_chal_1_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_BLOCKED_KA, blocked_ka_alarm_expired, conn);
|
||||
lsquic_rechist_init(&conn->ifc_rechist[PNS_INIT], &conn->ifc_conn, 1);
|
||||
lsquic_rechist_init(&conn->ifc_rechist[PNS_HSK], &conn->ifc_conn, 1);
|
||||
lsquic_rechist_init(&conn->ifc_rechist[PNS_APP], &conn->ifc_conn, 1);
|
||||
|
@ -949,8 +1034,6 @@ ietf_full_conn_init (struct ietf_full_conn *conn,
|
|||
conn->ifc_paths[1].cop_path.np_path_id = 1;
|
||||
#define valid_stream_id(v) ((v) <= VINT_MAX_VALUE)
|
||||
conn->ifc_max_req_id = VINT_MAX_VALUE + 1;
|
||||
conn->ifc_idle_to = enpub->enp_settings.es_idle_timeout * 1000 * 1000;
|
||||
conn->ifc_ping_period = enpub->enp_settings.es_ping_period * 1000 * 1000;
|
||||
conn->ifc_ping_unretx_thresh = 20;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1035,7 +1118,8 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
|
|||
if (conn->ifc_settings->es_handshake_to)
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_HANDSHAKE,
|
||||
lsquic_time_now() + conn->ifc_settings->es_handshake_to);
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE, now + conn->ifc_idle_to);
|
||||
if (conn->ifc_idle_to)
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE, now + conn->ifc_idle_to);
|
||||
if (enpub->enp_settings.es_support_push && CLIENT_PUSH_SUPPORT)
|
||||
{
|
||||
conn->ifc_u.cli.ifcli_flags |= IFCLI_PUSH_ENABLED;
|
||||
|
@ -1134,10 +1218,9 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
|
|||
if (cce->cce_seqno > conn->ifc_scid_seqno)
|
||||
conn->ifc_scid_seqno = cce->cce_seqno;
|
||||
conn->ifc_conn.cn_cces[i].cce_seqno = cce->cce_seqno;
|
||||
conn->ifc_scid_timestamp[i] = now;
|
||||
++conn->ifc_active_cids_count;
|
||||
}
|
||||
else
|
||||
conn->ifc_original_cids |= 1 << i;
|
||||
conn->ifc_scid_timestamp[i] = now;
|
||||
}
|
||||
++conn->ifc_scid_seqno;
|
||||
|
||||
|
@ -1265,14 +1348,10 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
|
|||
conn->ifc_incoming_ecn = imc->imc_incoming_ecn;
|
||||
conn->ifc_pub.rtt_stats = imc->imc_rtt_stats;
|
||||
|
||||
if (conn->ifc_original_cids)
|
||||
{
|
||||
lsquic_time_t now = lsquic_time_now();
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_RET_CIDS,
|
||||
ret_cids_alarm_expired, conn);
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_RET_CIDS,
|
||||
now + RET_CID_TIMEOUT);
|
||||
}
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_RET_CIDS,
|
||||
ret_cids_alarm_expired, conn);
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_RET_CIDS,
|
||||
now + RET_CID_TIMEOUT);
|
||||
|
||||
conn->ifc_last_live_update = now;
|
||||
|
||||
|
@ -1285,7 +1364,8 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
|
|||
if (0 != handshake_ok(&conn->ifc_conn))
|
||||
goto err3;
|
||||
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE,
|
||||
if (conn->ifc_idle_to)
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE,
|
||||
imc->imc_created + conn->ifc_idle_to);
|
||||
while ((packet_in = TAILQ_FIRST(&imc->imc_app_packets)))
|
||||
{
|
||||
|
@ -1504,7 +1584,16 @@ generate_max_data_frame (struct ietf_full_conn *conn)
|
|||
static int
|
||||
can_issue_cids (const struct ietf_full_conn *conn)
|
||||
{
|
||||
return conn->ifc_active_cids_count < conn->ifc_active_cids_limit;
|
||||
int can;
|
||||
|
||||
can = ((1 << conn->ifc_conn.cn_n_cces) - 1
|
||||
!= conn->ifc_conn.cn_cces_mask)
|
||||
&& conn->ifc_active_cids_count < conn->ifc_active_cids_limit;
|
||||
LSQ_DEBUG("can issue CIDs: %d (n_cces %hhu; mask: 0x%hhX; "
|
||||
"active: %hhu; limit: %hhu)",
|
||||
can, conn->ifc_conn.cn_n_cces, conn->ifc_conn.cn_cces_mask,
|
||||
conn->ifc_active_cids_count, conn->ifc_active_cids_limit);
|
||||
return can;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1556,10 +1645,8 @@ generate_new_cid_frame (struct ietf_full_conn *conn, lsquic_time_t now)
|
|||
conn->ifc_conn.cn_pf, packet_out->po_data + packet_out->po_data_sz, w);
|
||||
packet_out->po_frame_types |= QUIC_FTBIT_NEW_CONNECTION_ID;
|
||||
lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, w);
|
||||
++conn->ifc_active_cids_count;
|
||||
|
||||
if ((1 << conn->ifc_conn.cn_n_cces) - 1 == conn->ifc_conn.cn_cces_mask
|
||||
|| !can_issue_cids(conn))
|
||||
if (!can_issue_cids(conn))
|
||||
{
|
||||
conn->ifc_send_flags &= ~SF_SEND_NEW_CID;
|
||||
LSQ_DEBUG("All %u SCID slots have been assigned",
|
||||
|
@ -1574,7 +1661,9 @@ static void
|
|||
maybe_get_rate_available_scid_slot (struct ietf_full_conn *conn,
|
||||
lsquic_time_t now)
|
||||
{
|
||||
unsigned i, active_cid;
|
||||
const struct lsquic_conn *const lconn = &conn->ifc_conn;
|
||||
const struct conn_cid_elem *cce;
|
||||
unsigned active_cid;
|
||||
lsquic_time_t total_elapsed, elapsed_thresh, period, wait_time;
|
||||
|
||||
if (!conn->ifc_enpub->enp_settings.es_scid_iss_rate)
|
||||
|
@ -1587,12 +1676,18 @@ maybe_get_rate_available_scid_slot (struct ietf_full_conn *conn,
|
|||
period = (60 * 1000000) / conn->ifc_enpub->enp_settings.es_scid_iss_rate;
|
||||
active_cid = 0;
|
||||
total_elapsed = 0;
|
||||
for (i = 0; i < MAX_SCID; i++)
|
||||
for (cce = lconn->cn_cces; cce < END_OF_CCES(lconn); ++cce)
|
||||
{
|
||||
if (conn->ifc_original_cids & (1 << i))
|
||||
continue;
|
||||
active_cid += 1;
|
||||
total_elapsed += (now - conn->ifc_scid_timestamp[i]);
|
||||
if ((cce->cce_flags & (CCE_SEQNO|CCE_PORT)) == CCE_SEQNO)
|
||||
{
|
||||
active_cid += 1;
|
||||
/* When server is promoted, the timestamp may be larger than the
|
||||
* first tick time.
|
||||
*/
|
||||
if (now > conn->ifc_scid_timestamp[cce - lconn->cn_cces])
|
||||
total_elapsed +=
|
||||
now - conn->ifc_scid_timestamp[cce - lconn->cn_cces];
|
||||
}
|
||||
}
|
||||
elapsed_thresh = ((active_cid * (active_cid + 1)) / 2) * period;
|
||||
/* compare total elapsed ns to elapsed ns threshold */
|
||||
|
@ -1623,6 +1718,7 @@ generate_new_cid_frames (struct ietf_full_conn *conn, lsquic_time_t now)
|
|||
maybe_get_rate_available_scid_slot(conn, now);
|
||||
}
|
||||
while (conn->ifc_send_flags & SF_SEND_NEW_CID);
|
||||
LOG_SCIDS(conn);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2306,6 +2402,25 @@ retire_dcid (struct ietf_full_conn *conn, struct dcid_elem **dce)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
retire_seqno (struct ietf_full_conn *conn, unsigned seqno)
|
||||
{
|
||||
struct dcid_elem *dce;
|
||||
|
||||
dce = lsquic_malo_get(conn->ifc_pub.mm->malo.dcid_elem);
|
||||
if (dce)
|
||||
{
|
||||
memset(dce, 0, sizeof(*dce));
|
||||
dce->de_seqno = seqno;
|
||||
TAILQ_INSERT_TAIL(&conn->ifc_to_retire, dce, de_next_to_ret);
|
||||
LSQ_DEBUG("prepare to retire DCID seqno %"PRIu32, seqno);
|
||||
conn->ifc_send_flags |= SF_SEND_RETIRE_CID;
|
||||
}
|
||||
else
|
||||
LSQ_INFO("%s: cannot allocate dce", __func__);
|
||||
}
|
||||
|
||||
|
||||
/* This function exists for testing purposes.
|
||||
*
|
||||
* The user can switch DCIDs and request that the old DCID is retired.
|
||||
|
@ -2785,7 +2900,42 @@ handshake_ok (struct lsquic_conn *lconn)
|
|||
= params->tp_init_max_stream_data_bidi_remote;
|
||||
conn->ifc_cfg.ack_exp = params->tp_ack_delay_exponent;
|
||||
|
||||
/* TODO: idle timeout, packet size */
|
||||
switch ((!!conn->ifc_settings->es_idle_timeout << 1)
|
||||
| !!params->tp_max_idle_timeout)
|
||||
{
|
||||
case (0 << 1) | 0:
|
||||
LSQ_DEBUG("neither side specified max idle time out, turn it off");
|
||||
break;
|
||||
case (0 << 1) | 1:
|
||||
LSQ_DEBUG("peer specified max idle timeout of %"PRIu64" ms (vs ours "
|
||||
"of zero): use it", params->tp_max_idle_timeout);
|
||||
conn->ifc_idle_to = params->tp_max_idle_timeout * 1000;
|
||||
break;
|
||||
case (1 << 1) | 0:
|
||||
LSQ_DEBUG("peer did not specify max idle timeout, while ours is "
|
||||
"%u ms: use it", conn->ifc_settings->es_idle_timeout * 1000);
|
||||
conn->ifc_idle_to = conn->ifc_settings->es_idle_timeout * 1000000;
|
||||
break;
|
||||
default:/* (1 << 1) | 1 */
|
||||
LSQ_DEBUG("our max idle timeout is %u ms, peer's is %"PRIu64" ms; "
|
||||
"use minimum value of %"PRIu64" ms",
|
||||
conn->ifc_settings->es_idle_timeout * 1000,
|
||||
params->tp_max_idle_timeout,
|
||||
MIN(conn->ifc_settings->es_idle_timeout * 1000,
|
||||
params->tp_max_idle_timeout));
|
||||
conn->ifc_idle_to = 1000 * MIN(conn->ifc_settings->es_idle_timeout
|
||||
* 1000, params->tp_max_idle_timeout);
|
||||
break;
|
||||
}
|
||||
|
||||
if (conn->ifc_idle_to >= 2000000
|
||||
&& conn->ifc_enpub->enp_settings.es_ping_period)
|
||||
conn->ifc_ping_period = conn->ifc_idle_to / 2;
|
||||
else
|
||||
conn->ifc_ping_period = 0;
|
||||
LSQ_DEBUG("PING period is set to %"PRIu64" usec", conn->ifc_ping_period);
|
||||
|
||||
/* TODO: packet size */
|
||||
|
||||
dce = get_new_dce(conn);
|
||||
if (!dce)
|
||||
|
@ -2878,9 +3028,7 @@ handshake_ok (struct lsquic_conn *lconn)
|
|||
conn->ifc_active_cids_limit = params->tp_active_connection_id_limit;
|
||||
conn->ifc_first_active_cid_seqno = conn->ifc_scid_seqno;
|
||||
|
||||
if ((1 << conn->ifc_conn.cn_n_cces) - 1 != conn->ifc_conn.cn_cces_mask
|
||||
&& can_issue_cids(conn)
|
||||
&& CN_SCID(&conn->ifc_conn)->len != 0)
|
||||
if (can_issue_cids(conn) && CN_SCID(&conn->ifc_conn)->len != 0)
|
||||
conn->ifc_send_flags |= SF_SEND_NEW_CID;
|
||||
maybe_create_delayed_streams(conn);
|
||||
|
||||
|
@ -3297,6 +3445,11 @@ ietf_full_conn_ci_is_tickable (struct lsquic_conn *lconn)
|
|||
LSQ_DEBUG("tickable: send flags: 0x%X", conn->ifc_send_flags);
|
||||
goto check_can_send;
|
||||
}
|
||||
if (conn->ifc_conn.cn_flags & LSCONN_SEND_BLOCKED)
|
||||
{
|
||||
LSQ_DEBUG("tickable: send DATA_BLOCKED frame");
|
||||
goto check_can_send;
|
||||
}
|
||||
if (conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE ?
|
||||
lsquic_send_ctl_has_buffered(&conn->ifc_send_ctl) :
|
||||
lsquic_send_ctl_has_buffered_high(&conn->ifc_send_ctl))
|
||||
|
@ -3819,6 +3972,22 @@ process_padding_frame (struct ietf_full_conn *conn,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
handshake_confirmed (struct ietf_full_conn *conn)
|
||||
{
|
||||
ignore_hsk(conn);
|
||||
/* Even in ID-25, we wait for 1-RTT ACK on the server before dropping keys.
|
||||
*/
|
||||
conn->ifc_conn.cn_esf.i->esfi_handshake_confirmed(
|
||||
conn->ifc_conn.cn_enc_session);
|
||||
if (!(conn->ifc_flags & (IFC_SERVER|IFC_MIGRA)))
|
||||
{
|
||||
conn->ifc_flags |= IFC_MIGRA; /* Perform migration just once */
|
||||
maybe_start_migration(conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
process_ack (struct ietf_full_conn *conn, struct ack_info *acki,
|
||||
lsquic_time_t received, lsquic_time_t now)
|
||||
|
@ -3841,11 +4010,7 @@ process_ack (struct ietf_full_conn *conn, struct ack_info *acki,
|
|||
{
|
||||
if (!(conn->ifc_flags & IFC_IGNORE_INIT))
|
||||
ignore_init(conn);
|
||||
ignore_hsk(conn);
|
||||
conn->ifc_conn.cn_esf.i->esfi_1rtt_acked(
|
||||
conn->ifc_conn.cn_enc_session);
|
||||
if (!(conn->ifc_flags & IFC_SERVER))
|
||||
maybe_start_migration(conn);
|
||||
handshake_confirmed(conn);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -4329,6 +4494,8 @@ process_crypto_frame (struct ietf_full_conn *conn,
|
|||
stream_frame);
|
||||
if (parsed_len < 0) {
|
||||
lsquic_malo_put(stream_frame);
|
||||
ABORT_QUIETLY(0, TEC_FRAME_ENCODING_ERROR,
|
||||
"cannot decode CRYPTO frame");
|
||||
return 0;
|
||||
}
|
||||
enc_level = lsquic_packet_in_enc_level(packet_in);
|
||||
|
@ -4409,6 +4576,8 @@ process_stream_frame (struct ietf_full_conn *conn,
|
|||
stream_frame);
|
||||
if (parsed_len < 0) {
|
||||
lsquic_malo_put(stream_frame);
|
||||
ABORT_QUIETLY(0, TEC_FRAME_ENCODING_ERROR,
|
||||
"cannot decode STREAM frame");
|
||||
return 0;
|
||||
}
|
||||
EV_LOG_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_frame);
|
||||
|
@ -4774,30 +4943,6 @@ retire_dcids_prior_to (struct ietf_full_conn *conn, unsigned retire_prior_to)
|
|||
}
|
||||
|
||||
|
||||
/* We need to be able to allocate a DCE slot to begin migration or to retire
|
||||
* the DCID in transport parameters.
|
||||
*/
|
||||
static int
|
||||
must_reserve_one_dce_slot (struct ietf_full_conn *conn)
|
||||
{
|
||||
struct lsquic_conn *const lconn = &conn->ifc_conn;
|
||||
const struct transport_params *params;
|
||||
|
||||
if (conn->ifc_flags & IFC_SERVER)
|
||||
return 0;
|
||||
|
||||
if (lsquic_send_ctl_1rtt_acked(&conn->ifc_send_ctl))
|
||||
return 0;
|
||||
|
||||
params = lconn->cn_esf.i->esfi_get_peer_transport_params(
|
||||
lconn->cn_enc_session);
|
||||
if (params) /* Just in case */
|
||||
return !!(params->tp_flags & (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
process_new_connection_id_frame (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
|
@ -4837,6 +4982,13 @@ process_new_connection_id_frame (struct ietf_full_conn *conn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (seqno < conn->ifc_last_retire_prior_to)
|
||||
{
|
||||
retire_seqno(conn, seqno);
|
||||
action_str = "Ignored (seqno smaller than last retire_prior_to";
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (retire_prior_to > conn->ifc_last_retire_prior_to)
|
||||
{
|
||||
conn->ifc_last_retire_prior_to = retire_prior_to;
|
||||
|
@ -4888,35 +5040,28 @@ process_new_connection_id_frame (struct ietf_full_conn *conn,
|
|||
else if (!dce)
|
||||
dce = el;
|
||||
|
||||
if (dce)
|
||||
if (!dce)
|
||||
{
|
||||
if (must_reserve_one_dce_slot(conn))
|
||||
{
|
||||
for (el = dce + 1; el < DCES_END(conn) && *el; ++el)
|
||||
;
|
||||
if (el == DCES_END(conn))
|
||||
{
|
||||
action_str = "Ignored (last slot reserved for migration)";
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
*dce = lsquic_malo_get(conn->ifc_pub.mm->malo.dcid_elem);
|
||||
if (*dce)
|
||||
{
|
||||
memset(*dce, 0, sizeof(**dce));
|
||||
(*dce)->de_seqno = seqno;
|
||||
(*dce)->de_cid = cid;
|
||||
memcpy((*dce)->de_srst, token, sizeof((*dce)->de_srst));
|
||||
(*dce)->de_flags |= DE_SRST;
|
||||
action_str = "Saved";
|
||||
if (update_cur_dcid)
|
||||
*CUR_DCID(conn) = cid;
|
||||
}
|
||||
else
|
||||
action_str = "Ignored (alloc failure)";
|
||||
ABORT_QUIETLY(0, TEC_CONNECTION_ID_LIMIT_ERROR,
|
||||
"NEW_CONNECTION_ID: received connection ID that is going over the "
|
||||
"limit of %u CIDs", MAX_IETF_CONN_DCIDS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*dce = lsquic_malo_get(conn->ifc_pub.mm->malo.dcid_elem);
|
||||
if (*dce)
|
||||
{
|
||||
memset(*dce, 0, sizeof(**dce));
|
||||
(*dce)->de_seqno = seqno;
|
||||
(*dce)->de_cid = cid;
|
||||
memcpy((*dce)->de_srst, token, sizeof((*dce)->de_srst));
|
||||
(*dce)->de_flags |= DE_SRST;
|
||||
action_str = "Saved";
|
||||
if (update_cur_dcid)
|
||||
*CUR_DCID(conn) = cid;
|
||||
}
|
||||
else
|
||||
action_str = "Ignored (no slots available)";
|
||||
action_str = "Ignored (alloc failure)";
|
||||
|
||||
end:
|
||||
LSQ_DEBUGC("Got new connection ID from peer: seq=%"PRIu64"; "
|
||||
|
@ -4935,11 +5080,12 @@ retire_cid (struct ietf_full_conn *conn, struct conn_cid_elem *cce,
|
|||
CID_BITS(&cce->cce_cid), cce->cce_seqno,
|
||||
(cce->cce_flags & CCE_SEQNO) ? "" : "original");
|
||||
|
||||
if (cce->cce_flags & CCE_SEQNO)
|
||||
--conn->ifc_active_cids_count;
|
||||
lsquic_engine_retire_cid(conn->ifc_enpub, lconn, cce - lconn->cn_cces, now);
|
||||
memset(cce, 0, sizeof(*cce));
|
||||
|
||||
if (((1 << conn->ifc_conn.cn_n_cces) - 1 != conn->ifc_conn.cn_cces_mask)
|
||||
&& can_issue_cids(conn)
|
||||
if (can_issue_cids(conn)
|
||||
&& !(lsquic_alarmset_is_set(&conn->ifc_alset, AL_CID_THROT)))
|
||||
maybe_get_rate_available_scid_slot(conn, now);
|
||||
}
|
||||
|
@ -4954,11 +5100,11 @@ process_retire_connection_id_frame (struct ietf_full_conn *conn,
|
|||
uint64_t seqno;
|
||||
int parsed_len;
|
||||
|
||||
/* [draft-ietf-quic-transport-20] Section 19.16
|
||||
/* [draft-ietf-quic-transport-25] Section 19.16
|
||||
*
|
||||
* - Peer cannot retire zero-lenth CID. (MUST treat as PROTOCOL_VIOLATION)
|
||||
* - Peer cannot retire CID with sequence number that has not been
|
||||
* allocated yet. (MAY treat as PROTOCOL_VIOLATION)
|
||||
* allocated yet. (MUST treat as PROTOCOL_VIOLATION)
|
||||
* - Peer cannot retire CID that matches the DCID in packet.
|
||||
* (MAY treat as PROTOCOL_VIOLATION)
|
||||
*/
|
||||
|
@ -5002,6 +5148,7 @@ process_retire_connection_id_frame (struct ietf_full_conn *conn,
|
|||
}
|
||||
else
|
||||
LSQ_DEBUG("cannot retire CID seqno=%"PRIu64": not found", seqno);
|
||||
LOG_SCIDS(conn);
|
||||
|
||||
return parsed_len;
|
||||
}
|
||||
|
@ -5120,7 +5267,7 @@ static unsigned
|
|||
process_blocked_frame (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
uint64_t peer_off, last_off;
|
||||
uint64_t peer_off;
|
||||
int parsed_len;
|
||||
|
||||
parsed_len = conn->ifc_conn.cn_pf->pf_parse_blocked_frame(p, len,
|
||||
|
@ -5132,25 +5279,43 @@ process_blocked_frame (struct ietf_full_conn *conn,
|
|||
peer_off);
|
||||
LSQ_DEBUG("received BLOCKED frame: offset %"PRIu64, peer_off);
|
||||
|
||||
if (conn->ifc_last_max_data_off_sent)
|
||||
last_off = conn->ifc_last_max_data_off_sent;
|
||||
else
|
||||
last_off = lsquic_cfcw_get_max_recv_off(&conn->ifc_pub.cfcw);
|
||||
|
||||
/* Same logic as in lsquic_stream_peer_blocked() */
|
||||
if (peer_off > last_off && !(conn->ifc_send_flags & SF_SEND_MAX_DATA))
|
||||
if (peer_off > conn->ifc_last_max_data_off_sent
|
||||
&& !(conn->ifc_send_flags & SF_SEND_MAX_DATA))
|
||||
{
|
||||
conn->ifc_send_flags |= SF_SEND_MAX_DATA;
|
||||
LSQ_DEBUG("marked to send MAX_DATA frame");
|
||||
}
|
||||
else if (conn->ifc_send_flags & SF_SEND_MAX_DATA)
|
||||
LSQ_DEBUG("MAX_STREAM_DATA frame is already scheduled");
|
||||
else if (conn->ifc_last_max_data_off_sent)
|
||||
LSQ_DEBUG("MAX_DATA(%"PRIu64") has already been either "
|
||||
"packetized or sent", conn->ifc_last_max_data_off_sent);
|
||||
else
|
||||
LSQ_INFO("Peer should have received transport param limit "
|
||||
"of %"PRIu64"; odd", last_off);
|
||||
LSQ_DEBUG("MAX_DATA(%"PRIu64") has already been either "
|
||||
"packetized or sent to peer", conn->ifc_last_max_data_off_sent);
|
||||
|
||||
return parsed_len;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
process_handshake_done_frame (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
int parsed_len;
|
||||
|
||||
parsed_len = conn->ifc_conn.cn_pf->pf_parse_handshake_done_frame(p, len);
|
||||
if (parsed_len < 0)
|
||||
return 0;
|
||||
|
||||
EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "HANDSHAKE_DONE frame in");
|
||||
LSQ_DEBUG("received HANDSHAKE_DONE frame");
|
||||
|
||||
if (conn->ifc_flags & IFC_SERVER)
|
||||
{
|
||||
ABORT_QUIETLY(0, TEC_PROTOCOL_VIOLATION,
|
||||
"Client cannot send HANDSHAKE_DONE frame");
|
||||
return 0;
|
||||
}
|
||||
|
||||
handshake_confirmed(conn);
|
||||
|
||||
return parsed_len;
|
||||
}
|
||||
|
@ -5182,6 +5347,7 @@ static process_frame_f const process_frames[N_QUIC_FRAMES] =
|
|||
[QUIC_FRAME_RETIRE_CONNECTION_ID] = process_retire_connection_id_frame,
|
||||
[QUIC_FRAME_STREAM] = process_stream_frame,
|
||||
[QUIC_FRAME_CRYPTO] = process_crypto_frame,
|
||||
[QUIC_FRAME_HANDSHAKE_DONE] = process_handshake_done_frame,
|
||||
};
|
||||
|
||||
|
||||
|
@ -5332,6 +5498,7 @@ on_new_or_unconfirmed_path (struct ietf_full_conn *conn,
|
|||
|
||||
path->cop_cce_idx = cce - lconn->cn_cces;
|
||||
cce->cce_flags |= CCE_USED;
|
||||
LOG_SCIDS(conn);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5435,6 +5602,49 @@ maybe_queue_opp_ack (struct ietf_full_conn *conn)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
verify_retry_packet (struct ietf_full_conn *conn,
|
||||
const struct lsquic_packet_in *packet_in)
|
||||
{
|
||||
unsigned char *pseudo_packet;
|
||||
size_t out_len, ad_len;
|
||||
int verified;
|
||||
|
||||
if (1 + CUR_DCID(conn)->len + packet_in->pi_data_sz > 0x1000)
|
||||
{
|
||||
/* Cover the theoretical possibility that we cannot fit the pseudo-
|
||||
* packet and 16-byte decrypted output into 4 KB:
|
||||
*/
|
||||
LSQ_INFO("%s: Retry packet is too long: %hu bytes", __func__,
|
||||
packet_in->pi_data_sz);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pseudo_packet = lsquic_mm_get_4k(conn->ifc_pub.mm);
|
||||
if (!pseudo_packet)
|
||||
{
|
||||
LSQ_INFO("%s: cannot allocate memory", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pseudo_packet[0] = CUR_DCID(conn)->len;
|
||||
memcpy(pseudo_packet + 1, CUR_DCID(conn)->idbuf, CUR_DCID(conn)->len);
|
||||
memcpy(pseudo_packet + 1 + CUR_DCID(conn)->len, packet_in->pi_data,
|
||||
packet_in->pi_data_sz);
|
||||
|
||||
out_len = 0;
|
||||
ad_len = 1 + CUR_DCID(conn)->len + packet_in->pi_data_sz - 16;
|
||||
verified = 1 == EVP_AEAD_CTX_open(conn->ifc_enpub->enp_retry_aead_ctx,
|
||||
pseudo_packet + ad_len, &out_len, out_len,
|
||||
IETF_RETRY_NONCE_BUF, IETF_RETRY_NONCE_SZ,
|
||||
pseudo_packet + ad_len, 16, pseudo_packet, ad_len)
|
||||
&& out_len == 0;
|
||||
|
||||
lsquic_mm_put_4k(conn->ifc_pub.mm, pseudo_packet);
|
||||
return verified ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
process_retry_packet (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in)
|
||||
|
@ -5467,14 +5677,8 @@ process_retry_packet (struct ietf_full_conn *conn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!(CUR_DCID(conn)->len == packet_in->pi_odcid_len
|
||||
&& 0 == memcmp(CUR_DCID(conn)->idbuf,
|
||||
packet_in->pi_data + packet_in->pi_odcid,
|
||||
packet_in->pi_odcid_len)))
|
||||
{
|
||||
LSQ_DEBUG("retry packet's ODCID does not match the original: ignore");
|
||||
if (0 != verify_retry_packet(conn, packet_in))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 != lsquic_send_ctl_retry(&conn->ifc_send_ctl,
|
||||
packet_in->pi_data + packet_in->pi_token,
|
||||
|
@ -5560,6 +5764,7 @@ on_dcid_change (struct ietf_full_conn *conn, const lsquic_cid_t *dcid_in)
|
|||
cce->cce_flags |= CCE_USED;
|
||||
lconn->cn_cur_cce_idx = cce - lconn->cn_cces;
|
||||
LSQ_DEBUGC("%s: set SCID to %"CID_FMT, __func__, CID_BITS(CN_SCID(lconn)));
|
||||
LOG_SCIDS(conn);
|
||||
|
||||
/* Reset spin bit, see [draft-ietf-quic-transport-20] Section 17.3.1 */
|
||||
conn->ifc_spin_bit = 0;
|
||||
|
@ -5928,7 +6133,8 @@ ietf_full_conn_ci_packet_in (struct lsquic_conn *lconn,
|
|||
{
|
||||
struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn;
|
||||
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE,
|
||||
if (conn->ifc_idle_to)
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE,
|
||||
packet_in->pi_received + conn->ifc_idle_to);
|
||||
if (0 == (conn->ifc_flags & IFC_IMMEDIATE_CLOSE_FLAGS))
|
||||
if (0 != conn->ifc_process_incoming_packet(conn, packet_in))
|
||||
|
@ -5989,6 +6195,12 @@ ietf_full_conn_ci_packet_sent (struct lsquic_conn *lconn,
|
|||
ABORT_ERROR("sent packet failed: %s", strerror(errno));
|
||||
++conn->ifc_ecn_counts_out[ lsquic_packet_out_pns(packet_out) ]
|
||||
[ lsquic_packet_out_ecn(packet_out) ];
|
||||
/* Set blocked keep-alive for a [1,8] seconds */
|
||||
if (packet_out->po_frame_types
|
||||
& (QUIC_FTBIT_BLOCKED|QUIC_FTBIT_STREAM_BLOCKED))
|
||||
lsquic_alarmset_set(&conn->ifc_alset, AL_BLOCKED_KA,
|
||||
packet_out->po_sent + (1 + (7 & lsquic_crand_get_nybble(
|
||||
conn->ifc_enpub->enp_crand))) * 1000000);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,7 +69,6 @@ enum http_error_code
|
|||
HEC_REQUEST_REJECTED = 0x10B,
|
||||
HEC_REQUEST_CANCELLED = 0x10C,
|
||||
HEC_REQUEST_INCOMPLETE = 0x10D,
|
||||
HEC_EARLY_RESPONSE = 0x10E,
|
||||
HEC_CONNECT_ERROR = 0x10F,
|
||||
HEC_VERSION_FALLBACK = 0x110,
|
||||
HEC_QPACK_DECOMPRESSION_FAILED = 0x200,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
/* Things specific to the IETF version of QUIC that do not fit anywhere else */
|
||||
|
||||
/* [draft-ietf-quic-transport-18] Section 22.3 */
|
||||
/* [draft-ietf-quic-transport-25] Section 22.4 */
|
||||
enum trans_error_code
|
||||
{
|
||||
TEC_NO_ERROR = 0x0,
|
||||
|
@ -16,12 +16,21 @@ enum trans_error_code
|
|||
TEC_FINAL_SIZE_ERROR = 0x6,
|
||||
TEC_FRAME_ENCODING_ERROR = 0x7,
|
||||
TEC_TRANSPORT_PARAMETER_ERROR = 0x8,
|
||||
TEC_VERSION_NEGOTIATION_ERROR = 0x9,
|
||||
TEC_CONNECTION_ID_LIMIT_ERROR = 0x9,
|
||||
TEC_PROTOCOL_VIOLATION = 0xA,
|
||||
TEC_INVALID_TOKEN = 0xB,
|
||||
TEC_CRYPTO_BUFFER_EXCEEDED = 0xD,
|
||||
};
|
||||
|
||||
/* Must be at least two */
|
||||
#define MAX_IETF_CONN_DCIDS 8
|
||||
|
||||
/* [draft-ietf-quic-tls-25] Section 5.8 */
|
||||
#define IETF_RETRY_KEY_BUF ((unsigned char *) \
|
||||
"\x4d\x32\xec\xdb\x2a\x21\x33\xc8\x41\xe4\x04\x3d\xf2\x7d\x44\x30")
|
||||
#define IETF_RETRY_KEY_SZ 16
|
||||
#define IETF_RETRY_NONCE_BUF ((unsigned char *) \
|
||||
"\x4d\x16\x11\xd0\x55\x13\xa5\x52\xc5\x87\xd5\x75")
|
||||
#define IETF_RETRY_NONCE_SZ 12
|
||||
|
||||
#endif
|
||||
|
|
|
@ -760,7 +760,10 @@ imico_process_crypto_frame (IMICO_PROC_FRAME_ARGS)
|
|||
parsed_len = conn->imc_conn.cn_pf->pf_parse_crypto_frame(p, len,
|
||||
&stream_frame);
|
||||
if (parsed_len < 0)
|
||||
{
|
||||
conn->imc_flags |= IMC_PARSE_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
enc_level = lsquic_packet_in_enc_level(packet_in);
|
||||
EV_LOG_CRYPTO_FRAME_IN(LSQUIC_LOG_CONN_ID, &stream_frame, enc_level);
|
||||
|
@ -903,7 +906,10 @@ imico_process_ack_frame (IMICO_PROC_FRAME_ARGS)
|
|||
parsed_len = conn->imc_conn.cn_pf->pf_parse_ack_frame(p, len, acki,
|
||||
ack_exp);
|
||||
if (parsed_len < 0)
|
||||
{
|
||||
conn->imc_flags |= IMC_PARSE_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pns = lsquic_hety2pns[ packet_in->pi_header_type ];
|
||||
acked = 0;
|
||||
|
@ -996,7 +1002,10 @@ imico_process_connection_close_frame (IMICO_PROC_FRAME_ARGS)
|
|||
parsed_len = conn->imc_conn.cn_pf->pf_parse_connect_close_frame(p, len,
|
||||
&app_error, &error_code, &reason_len, &reason_off);
|
||||
if (parsed_len < 0)
|
||||
{
|
||||
conn->imc_flags |= IMC_PARSE_FAILED;
|
||||
return 0;
|
||||
}
|
||||
EV_LOG_CONNECTION_CLOSE_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code,
|
||||
(int) reason_len, (const char *) p + reason_off);
|
||||
LSQ_INFO("Received CONNECTION_CLOSE frame (%s-level code: %"PRIu64"; "
|
||||
|
@ -1039,6 +1048,7 @@ static unsigned (*const imico_process_frames[N_QUIC_FRAMES])
|
|||
[QUIC_FRAME_PATH_RESPONSE] = imico_process_invalid_frame,
|
||||
/* STREAM frame can only come in the App PNS and we delay those packets: */
|
||||
[QUIC_FRAME_STREAM] = imico_process_invalid_frame,
|
||||
[QUIC_FRAME_HANDSHAKE_DONE] = imico_process_invalid_frame,
|
||||
};
|
||||
|
||||
|
||||
|
@ -1540,6 +1550,13 @@ imico_generate_conn_close (struct ietf_mini_conn *conn)
|
|||
reason = "handshake failed";
|
||||
rlen = 16;
|
||||
}
|
||||
else if (conn->imc_flags & IMC_PARSE_FAILED)
|
||||
{
|
||||
is_app = 0;
|
||||
error_code = TEC_FRAME_ENCODING_ERROR;
|
||||
reason = "cannot decode frame";
|
||||
rlen = 19;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_app = 0;
|
||||
|
@ -1605,6 +1622,34 @@ imico_generate_conn_close (struct ietf_mini_conn *conn)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
imico_generate_handshake_done (struct ietf_mini_conn *conn)
|
||||
{
|
||||
struct lsquic_packet_out *packet_out;
|
||||
unsigned need;
|
||||
int sz;
|
||||
|
||||
need = conn->imc_conn.cn_pf->pf_handshake_done_frame_size();
|
||||
packet_out = imico_get_packet_out(conn, HETY_NOT_SET, need);
|
||||
if (!packet_out)
|
||||
return -1;
|
||||
sz = conn->imc_conn.cn_pf->pf_gen_handshake_done_frame(
|
||||
packet_out->po_data + packet_out->po_data_sz,
|
||||
lsquic_packet_out_avail(packet_out));
|
||||
if (sz < 0)
|
||||
{
|
||||
LSQ_WARN("could not generate HANDSHAKE_DONE frame");
|
||||
return -1;
|
||||
}
|
||||
|
||||
packet_out->po_frame_types |= 1 << QUIC_FRAME_HANDSHAKE_DONE;
|
||||
packet_out->po_data_sz += sz;
|
||||
LSQ_DEBUG("generated HANDSHAKE_DONE frame");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static enum tick_st
|
||||
ietf_mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now)
|
||||
{
|
||||
|
@ -1633,12 +1678,18 @@ ietf_mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now)
|
|||
|
||||
if (conn->imc_flags & IMC_ERROR)
|
||||
{
|
||||
close_on_error:
|
||||
if (!(conn->imc_flags & IMC_CLOSE_RECVD))
|
||||
imico_generate_conn_close(conn);
|
||||
tick |= TICK_CLOSE;
|
||||
}
|
||||
else if (conn->imc_flags & IMC_HSK_OK)
|
||||
{
|
||||
if (conn->imc_conn.cn_version > LSQVER_ID24
|
||||
&& 0 != imico_generate_handshake_done(conn))
|
||||
goto close_on_error;
|
||||
tick |= TICK_PROMOTE;
|
||||
}
|
||||
|
||||
if (imico_have_packets_to_send(conn, now))
|
||||
tick |= TICK_SEND;
|
||||
|
|
|
@ -55,6 +55,7 @@ struct ietf_mini_conn
|
|||
IMC_ADDR_VALIDATED = 1 << 17,
|
||||
IMC_HSK_PACKET_SENT = 1 << 18,
|
||||
IMC_CLOSE_RECVD = 1 << 19,
|
||||
IMC_PARSE_FAILED = 1 << 20,
|
||||
} imc_flags;
|
||||
struct mini_crypto_stream imc_streams[N_ENC_LEVS];
|
||||
void *imc_stream_ps[N_ENC_LEVS];
|
||||
|
|
|
@ -33,6 +33,7 @@ enum quic_frame_type
|
|||
QUIC_FRAME_CRYPTO, /* B */
|
||||
QUIC_FRAME_RETIRE_CONNECTION_ID,/* I */
|
||||
QUIC_FRAME_NEW_TOKEN, /* I */
|
||||
QUIC_FRAME_HANDSHAKE_DONE, /* I */
|
||||
N_QUIC_FRAMES
|
||||
};
|
||||
|
||||
|
@ -60,6 +61,7 @@ enum quic_ft_bit {
|
|||
QUIC_FTBIT_CRYPTO = 1 << QUIC_FRAME_CRYPTO,
|
||||
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,
|
||||
};
|
||||
|
||||
static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
|
||||
|
@ -86,6 +88,7 @@ static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
|
|||
[QUIC_FRAME_CRYPTO] = "QUIC_FRAME_CRYPTO",
|
||||
[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",
|
||||
};
|
||||
|
||||
#define QUIC_FRAME_PRELEN (sizeof("QUIC_FRAME_"))
|
||||
|
@ -120,6 +123,7 @@ static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
|
|||
QUIC_FRAME_SLEN(QUIC_FRAME_RETIRE_CONNECTION_ID) \
|
||||
+ 1 + \
|
||||
QUIC_FRAME_SLEN(QUIC_FRAME_NEW_TOKEN) + 1 + \
|
||||
QUIC_FRAME_SLEN(QUIC_FRAME_HANDSHAKE_DONE) + 1 + \
|
||||
0
|
||||
|
||||
|
||||
|
@ -207,6 +211,7 @@ extern const char *const lsquic_pns2str[];
|
|||
| QUIC_FTBIT_PATH_RESPONSE \
|
||||
| QUIC_FTBIT_RETIRE_CONNECTION_ID \
|
||||
| QUIC_FTBIT_NEW_TOKEN \
|
||||
| QUIC_FTBIT_HANDSHAKE_DONE \
|
||||
| QUIC_FTBIT_CRYPTO )
|
||||
|
||||
/* [draft-ietf-quic-transport-24] Section 1.2 */
|
||||
|
|
|
@ -91,7 +91,7 @@ typedef struct lsquic_packet_in
|
|||
/* pi_token and pi_token_size are set in Initial and Retry packets */
|
||||
unsigned short pi_token_size; /* Size of the token */
|
||||
unsigned char pi_token; /* Offset to token */
|
||||
/* pi_odcid and pi_odcid_len are only set in Retry packets */
|
||||
/* pi_odcid and pi_odcid_len are only set in Retry packets for I-D < 25 */
|
||||
unsigned char pi_odcid; /* Offset to Original DCID */
|
||||
unsigned char pi_odcid_len; /* Size of ODCID */
|
||||
unsigned char pi_scid_off; /* Offset to SCID */
|
||||
|
|
|
@ -139,7 +139,7 @@ typedef struct lsquic_packet_out
|
|||
POL_ELBIT_0 = 1 << 1, /* EL bits encode the crypto level. */
|
||||
POL_ELBIT_1 = 1 << 2,
|
||||
#define POKP_SHIFT 3
|
||||
POL_KEY_PHASE= 1 << 3, /* Used for logging */
|
||||
POL_KEY_PHASE= 1 << 3,
|
||||
#define POECN_SHIFT 4
|
||||
POL_ECNBIT_0 = 1 << 4,
|
||||
POL_ECNBIT_1 = 1 << 5,
|
||||
|
@ -210,8 +210,6 @@ typedef struct lsquic_packet_out
|
|||
(p)->po_flags |= ((b) & 1) << POSPIN_SHIFT; \
|
||||
} while (0)
|
||||
|
||||
#define lsquic_packet_out_key_phase(p) 0 /* TODO */
|
||||
|
||||
#define lsquic_po_header_length(lconn, po_flags, dcid_len) ( \
|
||||
lconn->cn_pf->pf_packout_max_header_size(lconn, po_flags, dcid_len))
|
||||
|
||||
|
|
|
@ -295,12 +295,19 @@ struct parse_funcs
|
|||
(*pf_path_resp_frame_size) (void);
|
||||
int
|
||||
(*pf_gen_path_resp_frame) (unsigned char *, size_t, uint64_t resp);
|
||||
int
|
||||
(*pf_gen_handshake_done_frame) (unsigned char *buf, size_t buf_len);
|
||||
int
|
||||
(*pf_parse_handshake_done_frame) (const unsigned char *buf, size_t buf_len);
|
||||
unsigned
|
||||
(*pf_handshake_done_frame_size) (void);
|
||||
};
|
||||
|
||||
|
||||
extern const struct parse_funcs lsquic_parse_funcs_gquic_Q043;
|
||||
extern const struct parse_funcs lsquic_parse_funcs_gquic_Q046;
|
||||
extern const struct parse_funcs lsquic_parse_funcs_gquic_Q050;
|
||||
extern const struct parse_funcs lsquic_parse_funcs_ietf_id24;
|
||||
extern const struct parse_funcs lsquic_parse_funcs_ietf_v1;
|
||||
|
||||
#define select_pf_by_ver(ver) ( \
|
||||
|
@ -310,6 +317,8 @@ extern const struct parse_funcs lsquic_parse_funcs_ietf_v1;
|
|||
&lsquic_parse_funcs_gquic_Q046 : \
|
||||
(1 << (ver)) & ((1 << LSQVER_050)|LSQUIC_EXPERIMENTAL_Q098) ? \
|
||||
&lsquic_parse_funcs_gquic_Q050 : \
|
||||
(1 << (ver)) & (1 << LSQVER_ID24) ? \
|
||||
&lsquic_parse_funcs_ietf_id24 : \
|
||||
&lsquic_parse_funcs_ietf_v1)
|
||||
|
||||
/* This function is gQUIC-version independent */
|
||||
|
|
|
@ -289,6 +289,36 @@ gquic_Q046_packno_info (const struct lsquic_conn *lconn,
|
|||
}
|
||||
|
||||
|
||||
/* No simple PRST for Q046 */
|
||||
static ssize_t
|
||||
gquic_Q046_generate_simple_prst (const lsquic_cid_t *cidp, unsigned char *buf,
|
||||
size_t buf_sz)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
gquic_Q046_handshake_done_frame_size (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gquic_Q046_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gquic_Q046_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
const struct parse_funcs lsquic_parse_funcs_gquic_Q046 =
|
||||
{
|
||||
.pf_gen_reg_pkt_header = gquic_Q046_gen_reg_pkt_header,
|
||||
|
@ -317,7 +347,7 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q046 =
|
|||
.pf_write_float_time16 = gquic_be_write_float_time16,
|
||||
.pf_read_float_time16 = gquic_be_read_float_time16,
|
||||
#endif
|
||||
.pf_generate_simple_prst = lsquic_generate_iquic_reset,
|
||||
.pf_generate_simple_prst = gquic_Q046_generate_simple_prst,
|
||||
.pf_parse_frame_type = lsquic_parse_frame_type_gquic_Q035_thru_Q046,
|
||||
.pf_turn_on_fin = lsquic_turn_on_fin_Q035_thru_Q046,
|
||||
.pf_packout_size = gquic_Q046_packout_size,
|
||||
|
@ -327,4 +357,7 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q046 =
|
|||
.pf_gen_crypto_frame = gquic_Q046_gen_crypto_frame,
|
||||
.pf_parse_crypto_frame = gquic_Q046_parse_crypto_frame,
|
||||
.pf_packno_info = gquic_Q046_packno_info,
|
||||
.pf_gen_handshake_done_frame = gquic_Q046_gen_handshake_done_frame,
|
||||
.pf_parse_handshake_done_frame = gquic_Q046_parse_handshake_done_frame,
|
||||
.pf_handshake_done_frame_size = gquic_Q046_handshake_done_frame_size,
|
||||
};
|
||||
|
|
|
@ -825,6 +825,36 @@ gquic_Q050_calc_crypto_frame_header_sz (uint64_t offset, unsigned data_sz)
|
|||
}
|
||||
|
||||
|
||||
/* No simple PRST for Q050 */
|
||||
static ssize_t
|
||||
gquic_Q050_generate_simple_prst (const lsquic_cid_t *cidp, unsigned char *buf,
|
||||
size_t buf_sz)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
gquic_Q050_handshake_done_frame_size (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gquic_Q050_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gquic_Q050_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
const struct parse_funcs lsquic_parse_funcs_gquic_Q050 =
|
||||
{
|
||||
.pf_gen_reg_pkt_header = gquic_Q050_gen_reg_pkt_header,
|
||||
|
@ -853,7 +883,7 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q050 =
|
|||
.pf_write_float_time16 = gquic_be_write_float_time16,
|
||||
.pf_read_float_time16 = gquic_be_read_float_time16,
|
||||
#endif
|
||||
.pf_generate_simple_prst = lsquic_generate_iquic_reset,
|
||||
.pf_generate_simple_prst = gquic_Q050_generate_simple_prst,
|
||||
.pf_parse_frame_type = gquic_Q050_parse_frame_type,
|
||||
.pf_turn_on_fin = lsquic_turn_on_fin_Q035_thru_Q046,
|
||||
.pf_packout_size = gquic_Q050_packout_size,
|
||||
|
@ -864,4 +894,7 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q050 =
|
|||
.pf_parse_crypto_frame = gquic_Q050_parse_crypto_frame,
|
||||
.pf_packno_info = gquic_Q050_packno_info,
|
||||
.pf_calc_crypto_frame_header_sz = gquic_Q050_calc_crypto_frame_header_sz,
|
||||
.pf_gen_handshake_done_frame = gquic_Q050_gen_handshake_done_frame,
|
||||
.pf_parse_handshake_done_frame = gquic_Q050_parse_handshake_done_frame,
|
||||
.pf_handshake_done_frame_size = gquic_Q050_handshake_done_frame_size,
|
||||
};
|
||||
|
|
|
@ -217,7 +217,7 @@ lsquic_cid_from_packet (const unsigned char *buf, size_t bufsz,
|
|||
}
|
||||
|
||||
|
||||
/* See [draft-ietf-quic-tls-19], Section 4 */
|
||||
/* See [draft-ietf-quic-transport-25], Section 12.4 (Table 3) */
|
||||
const enum quic_ft_bit lsquic_legal_frames_by_level[N_ENC_LEVS] =
|
||||
{
|
||||
[ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||
|
@ -230,7 +230,7 @@ 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_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN,
|
||||
| QUIC_FTBIT_RETIRE_CONNECTION_ID,
|
||||
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||
| QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE,
|
||||
[ENC_LEV_FORW] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
|
||||
|
@ -242,5 +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_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN,
|
||||
};
|
||||
|
|
|
@ -69,9 +69,6 @@ lsquic_iquic_gen_retry_pkt (unsigned char *buf, size_t bufsz,
|
|||
const struct lsquic_engine_public *, const lsquic_cid_t *scid,
|
||||
const lsquic_cid_t *dcid, enum lsquic_version, const struct sockaddr *,
|
||||
uint8_t random_nybble);
|
||||
ssize_t
|
||||
lsquic_generate_iquic_reset (const lsquic_cid_t *, unsigned char *buf,
|
||||
size_t buf_sz);
|
||||
|
||||
#define GQUIC_RESET_SZ 33
|
||||
ssize_t
|
||||
|
|
|
@ -1010,6 +1010,27 @@ gquic_be_packno_info (const struct lsquic_conn *lconn,
|
|||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
gquic_Q043_handshake_done_frame_size (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gquic_Q043_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gquic_Q043_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
const struct parse_funcs lsquic_parse_funcs_gquic_Q043 =
|
||||
{
|
||||
.pf_gen_reg_pkt_header = gquic_be_gen_reg_pkt_header,
|
||||
|
@ -1049,4 +1070,7 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q043 =
|
|||
.pf_gen_crypto_frame = gquic_be_gen_crypto_frame,
|
||||
.pf_parse_crypto_frame = gquic_be_parse_crypto_frame,
|
||||
.pf_packno_info = gquic_be_packno_info,
|
||||
.pf_gen_handshake_done_frame = gquic_Q043_gen_handshake_done_frame,
|
||||
.pf_parse_handshake_done_frame = gquic_Q043_parse_handshake_done_frame,
|
||||
.pf_handshake_done_frame_size = gquic_Q043_handshake_done_frame_size,
|
||||
};
|
||||
|
|
|
@ -266,7 +266,7 @@ gen_short_pkt_header (const struct lsquic_conn *lconn,
|
|||
| (lsquic_packet_out_spin_bit(packet_out) << 5)
|
||||
| (lsquic_packet_out_square_bit(packet_out) << 4)
|
||||
| (lsquic_packet_out_loss_bit(packet_out) << 3)
|
||||
| (lsquic_packet_out_key_phase(packet_out) << 2)
|
||||
| (lsquic_packet_out_kp(packet_out) << 2)
|
||||
| packno_bits
|
||||
;
|
||||
|
||||
|
@ -529,6 +529,10 @@ ietf_v1_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz,
|
|||
else
|
||||
data_sz = pend - p;
|
||||
|
||||
/* Largest offset cannot exceed this value and we MUST detect this error */
|
||||
if (VINT_MAX_VALUE - offset < data_sz)
|
||||
return -1;
|
||||
|
||||
stream_frame->stream_id = stream_id;
|
||||
stream_frame->data_frame.df_fin = type & 0x1;
|
||||
stream_frame->data_frame.df_offset = offset;
|
||||
|
@ -567,6 +571,10 @@ lsquic_ietf_v1_parse_crypto_frame (const unsigned char *buf,
|
|||
p += r;
|
||||
CHECK_SPACE(data_sz, p, pend);
|
||||
|
||||
/* Largest offset cannot exceed this value and we MUST detect this error */
|
||||
if (VINT_MAX_VALUE - offset < data_sz)
|
||||
return -1;
|
||||
|
||||
stream_frame->stream_id = ~0ULL; /* Unset */
|
||||
stream_frame->data_frame.df_fin = 0;
|
||||
stream_frame->data_frame.df_offset = offset;
|
||||
|
@ -1096,6 +1104,273 @@ ietf_v1_parse_frame_type (unsigned char byte)
|
|||
}
|
||||
|
||||
|
||||
static enum quic_frame_type
|
||||
ietf_id24_parse_frame_type (unsigned char byte)
|
||||
{
|
||||
/* This one does not have QUIC_FRAME_HANDSHAKE_DONE */
|
||||
static const enum quic_frame_type byte2type[0x100] =
|
||||
{
|
||||
[0x00] = QUIC_FRAME_PADDING,
|
||||
[0x01] = QUIC_FRAME_PING,
|
||||
[0x02] = QUIC_FRAME_ACK,
|
||||
[0x03] = QUIC_FRAME_ACK,
|
||||
[0x04] = QUIC_FRAME_RST_STREAM,
|
||||
[0x05] = QUIC_FRAME_STOP_SENDING,
|
||||
[0x06] = QUIC_FRAME_CRYPTO,
|
||||
[0x07] = QUIC_FRAME_NEW_TOKEN,
|
||||
[0x08] = QUIC_FRAME_STREAM,
|
||||
[0x09] = QUIC_FRAME_STREAM,
|
||||
[0x0A] = QUIC_FRAME_STREAM,
|
||||
[0x0B] = QUIC_FRAME_STREAM,
|
||||
[0x0C] = QUIC_FRAME_STREAM,
|
||||
[0x0D] = QUIC_FRAME_STREAM,
|
||||
[0x0E] = QUIC_FRAME_STREAM,
|
||||
[0x0F] = QUIC_FRAME_STREAM,
|
||||
[0x10] = QUIC_FRAME_MAX_DATA,
|
||||
[0x11] = QUIC_FRAME_MAX_STREAM_DATA,
|
||||
[0x12] = QUIC_FRAME_MAX_STREAMS,
|
||||
[0x13] = QUIC_FRAME_MAX_STREAMS,
|
||||
[0x14] = QUIC_FRAME_BLOCKED,
|
||||
[0x15] = QUIC_FRAME_STREAM_BLOCKED,
|
||||
[0x16] = QUIC_FRAME_STREAMS_BLOCKED,
|
||||
[0x17] = QUIC_FRAME_STREAMS_BLOCKED,
|
||||
[0x18] = QUIC_FRAME_NEW_CONNECTION_ID,
|
||||
[0x19] = QUIC_FRAME_RETIRE_CONNECTION_ID,
|
||||
[0x1A] = QUIC_FRAME_PATH_CHALLENGE,
|
||||
[0x1B] = QUIC_FRAME_PATH_RESPONSE,
|
||||
[0x1C] = QUIC_FRAME_CONNECTION_CLOSE,
|
||||
[0x1D] = QUIC_FRAME_CONNECTION_CLOSE,
|
||||
[0x1E] = QUIC_FRAME_INVALID,
|
||||
[0x1F] = QUIC_FRAME_INVALID,
|
||||
[0x20] = QUIC_FRAME_INVALID,
|
||||
[0x21] = QUIC_FRAME_INVALID,
|
||||
[0x22] = QUIC_FRAME_INVALID,
|
||||
[0x23] = QUIC_FRAME_INVALID,
|
||||
[0x24] = QUIC_FRAME_INVALID,
|
||||
[0x25] = QUIC_FRAME_INVALID,
|
||||
[0x26] = QUIC_FRAME_INVALID,
|
||||
[0x27] = QUIC_FRAME_INVALID,
|
||||
[0x28] = QUIC_FRAME_INVALID,
|
||||
[0x29] = QUIC_FRAME_INVALID,
|
||||
[0x2A] = QUIC_FRAME_INVALID,
|
||||
[0x2B] = QUIC_FRAME_INVALID,
|
||||
[0x2C] = QUIC_FRAME_INVALID,
|
||||
[0x2D] = QUIC_FRAME_INVALID,
|
||||
[0x2E] = QUIC_FRAME_INVALID,
|
||||
[0x2F] = QUIC_FRAME_INVALID,
|
||||
[0x30] = QUIC_FRAME_INVALID,
|
||||
[0x31] = QUIC_FRAME_INVALID,
|
||||
[0x32] = QUIC_FRAME_INVALID,
|
||||
[0x33] = QUIC_FRAME_INVALID,
|
||||
[0x34] = QUIC_FRAME_INVALID,
|
||||
[0x35] = QUIC_FRAME_INVALID,
|
||||
[0x36] = QUIC_FRAME_INVALID,
|
||||
[0x37] = QUIC_FRAME_INVALID,
|
||||
[0x38] = QUIC_FRAME_INVALID,
|
||||
[0x39] = QUIC_FRAME_INVALID,
|
||||
[0x3A] = QUIC_FRAME_INVALID,
|
||||
[0x3B] = QUIC_FRAME_INVALID,
|
||||
[0x3C] = QUIC_FRAME_INVALID,
|
||||
[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];
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
ietf_v1_path_chal_frame_size (void)
|
||||
{
|
||||
|
@ -1695,14 +1970,32 @@ lsquic_ietf_v1_parse_packet_in_long_begin (struct lsquic_packet_in *packet_in,
|
|||
case HETY_RETRY:
|
||||
if (p >= end)
|
||||
return -1;
|
||||
odcil = *p++;
|
||||
if (p + odcil > end || odcil > MAX_CID_LEN)
|
||||
return -1;
|
||||
packet_in->pi_odcid_len = odcil;
|
||||
packet_in->pi_odcid = p - packet_in->pi_data;
|
||||
p += odcil;
|
||||
packet_in->pi_token = p - packet_in->pi_data;
|
||||
packet_in->pi_token_size = end - p;
|
||||
if (LSQVER_ID24 == lsquic_tag2ver(tag))
|
||||
{
|
||||
odcil = *p++;
|
||||
if (p + odcil > end || odcil > MAX_CID_LEN)
|
||||
return -1;
|
||||
packet_in->pi_odcid_len = odcil;
|
||||
packet_in->pi_odcid = p - packet_in->pi_data;
|
||||
p += odcil;
|
||||
packet_in->pi_token = p - packet_in->pi_data;
|
||||
packet_in->pi_token_size = end - p;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p
|
||||
/* [draft-ietf-quic-transport-25] Section 17.2.5 says that "a
|
||||
* client MUST discard a Retry packet with a zero-length Retry
|
||||
* Token field." We might as well do it here.
|
||||
*/
|
||||
+ 1
|
||||
/* Integrity tag length: */
|
||||
+ 16 > end)
|
||||
return -1;
|
||||
packet_in->pi_token = p - packet_in->pi_data;
|
||||
packet_in->pi_token_size = end - p - 16;
|
||||
/* Tag validation happens later */
|
||||
}
|
||||
p = end;
|
||||
length = end - packet_in->pi_data;
|
||||
state->pps_p = NULL;
|
||||
|
@ -1937,6 +2230,117 @@ lsquic_ietf_v1_gen_ver_nego_pkt (unsigned char *buf, size_t bufsz,
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_v1_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
if (buf_len > 0)
|
||||
{
|
||||
*buf = 0x1E;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_v1_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
assert(buf[0] == 0x1E);
|
||||
assert(buf_len > 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
ietf_v1_handshake_done_frame_size (void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_id24_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
/* ID-24 does not have HANDSHAKE_DONE frame */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_id24_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
/* ID-24 does not have HANDSHAKE_DONE frame */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
const struct parse_funcs lsquic_parse_funcs_ietf_id24 =
|
||||
{
|
||||
.pf_gen_reg_pkt_header = ietf_v1_gen_reg_pkt_header,
|
||||
.pf_parse_packet_in_finish = ietf_v1_parse_packet_in_finish,
|
||||
.pf_gen_stream_frame = ietf_v1_gen_stream_frame,
|
||||
.pf_calc_stream_frame_header_sz = ietf_v1_calc_stream_frame_header_sz,
|
||||
.pf_parse_stream_frame = ietf_v1_parse_stream_frame,
|
||||
.pf_parse_ack_frame = ietf_v1_parse_ack_frame,
|
||||
.pf_gen_ack_frame = ietf_v1_gen_ack_frame,
|
||||
.pf_gen_blocked_frame = ietf_v1_gen_blocked_frame,
|
||||
.pf_parse_blocked_frame = ietf_v1_parse_blocked_frame,
|
||||
.pf_blocked_frame_size = ietf_v1_blocked_frame_size,
|
||||
.pf_rst_frame_size = ietf_v1_rst_frame_size,
|
||||
.pf_gen_rst_frame = ietf_v1_gen_rst_frame,
|
||||
.pf_parse_rst_frame = ietf_v1_parse_rst_frame,
|
||||
.pf_connect_close_frame_size = ietf_v1_connect_close_frame_size,
|
||||
.pf_gen_connect_close_frame = ietf_v1_gen_connect_close_frame,
|
||||
.pf_parse_connect_close_frame = ietf_v1_parse_connect_close_frame,
|
||||
.pf_gen_ping_frame = ietf_v1_gen_ping_frame,
|
||||
.pf_parse_frame_type = ietf_id24_parse_frame_type,
|
||||
.pf_turn_on_fin = ietf_v1_turn_on_fin,
|
||||
.pf_packout_size = ietf_v1_packout_size,
|
||||
.pf_packout_max_header_size = ietf_v1_packout_max_header_size,
|
||||
.pf_path_chal_frame_size = ietf_v1_path_chal_frame_size,
|
||||
.pf_parse_path_chal_frame = ietf_v1_parse_path_chal_frame,
|
||||
.pf_gen_path_chal_frame = ietf_v1_gen_path_chal_frame,
|
||||
.pf_path_resp_frame_size = ietf_v1_path_resp_frame_size,
|
||||
.pf_gen_path_resp_frame = ietf_v1_gen_path_resp_frame,
|
||||
.pf_parse_path_resp_frame = ietf_v1_parse_path_resp_frame,
|
||||
.pf_calc_packno_bits = ietf_v1_calc_packno_bits,
|
||||
.pf_packno_bits2len = ietf_v1_packno_bits2len,
|
||||
.pf_packno_info = ietf_v1_packno_info,
|
||||
.pf_gen_crypto_frame = ietf_v1_gen_crypto_frame,
|
||||
.pf_parse_crypto_frame = ietf_v1_parse_crypto_frame,
|
||||
.pf_calc_crypto_frame_header_sz = ietf_v1_calc_crypto_frame_header_sz,
|
||||
.pf_parse_max_data = ietf_v1_parse_max_data,
|
||||
.pf_gen_max_data_frame = ietf_v1_gen_max_data_frame,
|
||||
.pf_max_data_frame_size = ietf_v1_max_data_frame_size,
|
||||
.pf_parse_new_conn_id = ietf_v1_parse_new_conn_id,
|
||||
.pf_gen_stream_blocked_frame = ietf_v1_gen_stream_blocked_frame,
|
||||
.pf_parse_stream_blocked_frame = ietf_v1_parse_stream_blocked_frame,
|
||||
.pf_stream_blocked_frame_size = ietf_v1_stream_blocked_frame_size,
|
||||
.pf_gen_max_stream_data_frame = ietf_v1_gen_max_stream_data_frame,
|
||||
.pf_parse_max_stream_data_frame = ietf_v1_parse_max_stream_data_frame,
|
||||
.pf_max_stream_data_frame_size = ietf_v1_max_stream_data_frame_size,
|
||||
.pf_parse_stop_sending_frame = ietf_v1_parse_stop_sending_frame,
|
||||
.pf_gen_stop_sending_frame = ietf_v1_gen_stop_sending_frame,
|
||||
.pf_stop_sending_frame_size = ietf_v1_stop_sending_frame_size,
|
||||
.pf_parse_new_token_frame = ietf_v1_parse_new_token_frame,
|
||||
.pf_new_connection_id_frame_size = ietf_v1_new_connection_id_frame_size,
|
||||
.pf_gen_new_connection_id_frame = ietf_v1_gen_new_connection_id_frame,
|
||||
.pf_new_token_frame_size = ietf_v1_new_token_frame_size,
|
||||
.pf_gen_new_token_frame = ietf_v1_gen_new_token_frame,
|
||||
.pf_parse_retire_cid_frame = ietf_v1_parse_retire_cid_frame,
|
||||
.pf_gen_retire_cid_frame = ietf_v1_gen_retire_cid_frame,
|
||||
.pf_retire_cid_frame_size = ietf_v1_retire_cid_frame_size,
|
||||
.pf_gen_streams_blocked_frame = ietf_v1_gen_streams_blocked_frame,
|
||||
.pf_parse_streams_blocked_frame = ietf_v1_parse_streams_blocked_frame,
|
||||
.pf_streams_blocked_frame_size = ietf_v1_streams_blocked_frame_size,
|
||||
.pf_gen_max_streams_frame = ietf_v1_gen_max_streams_frame,
|
||||
.pf_parse_max_streams_frame = ietf_v1_parse_max_streams_frame,
|
||||
.pf_max_streams_frame_size = ietf_v1_max_streams_frame_size,
|
||||
.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,
|
||||
};
|
||||
|
||||
|
||||
const struct parse_funcs lsquic_parse_funcs_ietf_v1 =
|
||||
|
@ -2001,4 +2405,7 @@ const struct parse_funcs lsquic_parse_funcs_ietf_v1 =
|
|||
.pf_gen_max_streams_frame = ietf_v1_gen_max_streams_frame,
|
||||
.pf_parse_max_streams_frame = ietf_v1_parse_max_streams_frame,
|
||||
.pf_max_streams_frame_size = ietf_v1_max_streams_frame_size,
|
||||
.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,
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "lsquic.h"
|
||||
#include "lsquic_mm.h"
|
||||
#include "lsquic_engine_public.h"
|
||||
#include "lsquic_ietf.h"
|
||||
|
||||
|
||||
/* [draft-ietf-quic-transport-17] Section-17.2 */
|
||||
|
@ -194,35 +195,6 @@ lsquic_Q046_parse_packet_in_short_begin (lsquic_packet_in_t *packet_in,
|
|||
}
|
||||
|
||||
|
||||
/* TODO: this only works Q044? XXX */
|
||||
ssize_t
|
||||
lsquic_generate_iquic_reset (const lsquic_cid_t *cidp, unsigned char *buf,
|
||||
size_t buf_sz)
|
||||
{
|
||||
size_t need;
|
||||
uint64_t id;
|
||||
|
||||
need = 1 /* Type */ + 20 /* Random bytes */ + 16 /* Reset token */;
|
||||
if (buf_sz < need)
|
||||
return -1;
|
||||
|
||||
*buf = 0x30;
|
||||
(void) RAND_pseudo_bytes(buf + 1, 20);
|
||||
/* XXX code duplication here and lsquic_generate_reset_token(). Which
|
||||
* should call which: parse function the crypto functions or the other
|
||||
* way around?
|
||||
*/
|
||||
/* TODO test this */
|
||||
memcpy(&id, cidp->idbuf, GQUIC_CID_LEN);
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
id = bswap_64(id);
|
||||
#endif
|
||||
memcpy(buf + 21, &id, sizeof(id));
|
||||
memset(buf + 21 + sizeof(id), 0, SRST_LENGTH - sizeof(id));
|
||||
return need;
|
||||
}
|
||||
|
||||
|
||||
/* This is a bare-bones version of lsquic_Q046_parse_packet_in_long_begin()
|
||||
*/
|
||||
int
|
||||
|
@ -300,7 +272,7 @@ const enum quic_frame_type lsquic_iquic_byte2type[0x100] =
|
|||
[0x1B] = QUIC_FRAME_PATH_RESPONSE,
|
||||
[0x1C] = QUIC_FRAME_CONNECTION_CLOSE,
|
||||
[0x1D] = QUIC_FRAME_CONNECTION_CLOSE,
|
||||
[0x1E] = QUIC_FRAME_INVALID,
|
||||
[0x1E] = QUIC_FRAME_HANDSHAKE_DONE,
|
||||
[0x1F] = QUIC_FRAME_INVALID,
|
||||
[0x20] = QUIC_FRAME_INVALID,
|
||||
[0x21] = QUIC_FRAME_INVALID,
|
||||
|
|
|
@ -2909,6 +2909,10 @@ lsquic_send_ctl_repath (struct lsquic_send_ctl *ctl, struct network_path *old,
|
|||
}
|
||||
|
||||
LSQ_DEBUG("repathed %u packet%.*s", count, count != 1, "s");
|
||||
|
||||
memset(&ctl->sc_conn_pub->rtt_stats, 0,
|
||||
sizeof(ctl->sc_conn_pub->rtt_stats));
|
||||
ctl->sc_ci->cci_reinit(CGP(ctl));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -610,4 +610,7 @@ lsquic_stream_header_is_trailer (const struct lsquic_stream *);
|
|||
int
|
||||
lsquic_stream_verify_len (struct lsquic_stream *, unsigned long long);
|
||||
|
||||
#define lsquic_stream_is_blocked(stream_) ((stream_)->blocked_off && \
|
||||
(stream_)->blocked_off == (stream_)->max_send_off)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -137,8 +137,8 @@ get_or_generate_state (struct lsquic_engine_public *enpub, time_t now,
|
|||
sizeof(TOKGEN_SHM_MAGIC_TOP) - 1);
|
||||
if (getenv("LSQUIC_NULL_TOKGEN"))
|
||||
{
|
||||
memset(&srst_ikm, 0, sizeof(srst_ikm));
|
||||
LSQ_NOTICE("using NULL tokgen");
|
||||
memset(&srst_ikm, 0, sizeof(srst_ikm));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@ static const uint64_t def_vals[MAX_TPI + 1] =
|
|||
[TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = TP_DEF_INIT_MAX_STREAM_DATA_BIDI_LOCAL,
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = TP_DEF_INIT_MAX_STREAM_DATA_BIDI_REMOTE,
|
||||
[TPI_INIT_MAX_STREAM_DATA_UNI] = TP_DEF_INIT_MAX_STREAM_DATA_UNI,
|
||||
[TPI_IDLE_TIMEOUT] = TP_DEF_IDLE_TIMEOUT,
|
||||
[TPI_MAX_IDLE_TIMEOUT] = TP_DEF_MAX_IDLE_TIMEOUT,
|
||||
[TPI_MAX_ACK_DELAY] = TP_DEF_MAX_ACK_DELAY,
|
||||
[TPI_ACTIVE_CONNECTION_ID_LIMIT] = TP_DEF_ACTIVE_CONNECTION_ID_LIMIT,
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ static const uint64_t max_vals[MAX_TPI + 1] =
|
|||
[TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = VINT_MAX_VALUE,
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = VINT_MAX_VALUE,
|
||||
[TPI_INIT_MAX_STREAM_DATA_UNI] = VINT_MAX_VALUE,
|
||||
[TPI_IDLE_TIMEOUT] = VINT_MAX_VALUE,
|
||||
[TPI_MAX_IDLE_TIMEOUT] = VINT_MAX_VALUE,
|
||||
[TPI_MAX_ACK_DELAY] = TP_MAX_MAX_ACK_DELAY,
|
||||
[TPI_ACTIVE_CONNECTION_ID_LIMIT] = VINT_MAX_VALUE,
|
||||
};
|
||||
|
@ -73,7 +73,7 @@ static const unsigned tpi2idx[MAX_TPI + 1] =
|
|||
[TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = TP_OFF(init_max_stream_data_bidi_local),
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = TP_OFF(init_max_stream_data_bidi_remote),
|
||||
[TPI_INIT_MAX_STREAM_DATA_UNI] = TP_OFF(init_max_stream_data_uni),
|
||||
[TPI_IDLE_TIMEOUT] = TP_OFF(idle_timeout),
|
||||
[TPI_MAX_IDLE_TIMEOUT] = TP_OFF(max_idle_timeout),
|
||||
[TPI_MAX_ACK_DELAY] = TP_OFF(max_ack_delay),
|
||||
[TPI_ACTIVE_CONNECTION_ID_LIMIT] = TP_OFF(active_connection_id_limit),
|
||||
};
|
||||
|
@ -533,7 +533,7 @@ lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
|
|||
WRITE_ONE_PARAM(init_max_stream_data_bidi_remote, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_stream_data_uni, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_data, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(idle_timeout, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(max_idle_timeout, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_streams_bidi, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_streams_uni, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(max_packet_size, "%"PRIu64);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
enum transport_param_id
|
||||
{
|
||||
TPI_ORIGINAL_CONNECTION_ID = 0,
|
||||
TPI_IDLE_TIMEOUT = 1,
|
||||
TPI_MAX_IDLE_TIMEOUT = 1,
|
||||
TPI_STATELESS_RESET_TOKEN = 2,
|
||||
TPI_MAX_PACKET_SIZE = 3,
|
||||
TPI_INIT_MAX_DATA = 4,
|
||||
|
@ -36,7 +36,7 @@ enum transport_param_id
|
|||
|(1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL) \
|
||||
|(1 << TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE) \
|
||||
|(1 << TPI_INIT_MAX_STREAM_DATA_UNI) \
|
||||
|(1 << TPI_IDLE_TIMEOUT) \
|
||||
|(1 << TPI_MAX_IDLE_TIMEOUT) \
|
||||
|(1 << TPI_MAX_ACK_DELAY) \
|
||||
|(1 << TPI_ACK_DELAY_EXPONENT) \
|
||||
|(1 << TPI_ACTIVE_CONNECTION_ID_LIMIT) \
|
||||
|
@ -74,7 +74,7 @@ struct transport_params
|
|||
uint64_t init_max_stream_data_bidi_remote;
|
||||
uint64_t init_max_stream_data_uni;
|
||||
uint64_t init_max_data;
|
||||
uint64_t idle_timeout;
|
||||
uint64_t max_idle_timeout;
|
||||
uint64_t init_max_streams_bidi;
|
||||
uint64_t init_max_streams_uni;
|
||||
uint64_t max_packet_size;
|
||||
|
@ -88,7 +88,7 @@ struct transport_params
|
|||
#define tp_init_max_stream_data_bidi_remote tp_numerics_u.s.init_max_stream_data_bidi_remote
|
||||
#define tp_init_max_stream_data_uni tp_numerics_u.s.init_max_stream_data_uni
|
||||
#define tp_init_max_data tp_numerics_u.s.init_max_data
|
||||
#define tp_idle_timeout tp_numerics_u.s.idle_timeout
|
||||
#define tp_max_idle_timeout tp_numerics_u.s.max_idle_timeout
|
||||
#define tp_init_max_streams_bidi tp_numerics_u.s.init_max_streams_bidi
|
||||
#define tp_init_max_streams_uni tp_numerics_u.s.init_max_streams_uni
|
||||
#define tp_max_packet_size tp_numerics_u.s.max_packet_size
|
||||
|
@ -119,16 +119,16 @@ struct transport_params
|
|||
#define TP_DEF_INIT_MAX_STREAM_DATA_BIDI_LOCAL 0
|
||||
#define TP_DEF_INIT_MAX_STREAM_DATA_BIDI_REMOTE 0
|
||||
#define TP_DEF_INIT_MAX_STREAM_DATA_UNI 0
|
||||
#define TP_DEF_IDLE_TIMEOUT 0
|
||||
#define TP_DEF_MAX_IDLE_TIMEOUT 0
|
||||
#define TP_DEF_MAX_ACK_DELAY 25
|
||||
#define TP_DEF_ACTIVE_CONNECTION_ID_LIMIT 0
|
||||
#define TP_DEF_ACTIVE_CONNECTION_ID_LIMIT 2
|
||||
|
||||
/* [draft-ietf-quic-transport-18], Section 18.1 */
|
||||
#define TP_MAX_MAX_ACK_DELAY ((1u << 14) - 1)
|
||||
|
||||
#define TP_DEFAULT_VALUES \
|
||||
.tp_active_connection_id_limit = TP_DEF_ACTIVE_CONNECTION_ID_LIMIT, \
|
||||
.tp_idle_timeout = TP_DEF_IDLE_TIMEOUT, \
|
||||
.tp_max_idle_timeout = TP_DEF_MAX_IDLE_TIMEOUT, \
|
||||
.tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY, \
|
||||
.tp_max_packet_size = TP_DEF_MAX_PACKET_SIZE, \
|
||||
.tp_ack_delay_exponent = TP_DEF_ACK_DELAY_EXP, \
|
||||
|
|
|
@ -14,8 +14,8 @@ static const unsigned char version_tags[N_LSQVER][4] =
|
|||
#if LSQUIC_USE_Q098
|
||||
[LSQVER_098] = { 'Q', '0', '9', '8', },
|
||||
#endif
|
||||
[LSQVER_ID23] = { 0xFF, 0, 0, 23, },
|
||||
[LSQVER_ID24] = { 0xFF, 0, 0, 24, },
|
||||
[LSQVER_ID25] = { 0xFF, 0, 0, 25, },
|
||||
[LSQVER_VERNEG] = { 0xFA, 0xFA, 0xFA, 0xFA, },
|
||||
};
|
||||
|
||||
|
@ -52,8 +52,8 @@ const char *const lsquic_ver2str[N_LSQVER] = {
|
|||
#if LSQUIC_USE_Q098
|
||||
[LSQVER_098] = "Q098",
|
||||
#endif
|
||||
[LSQVER_ID23] = "FF000017",
|
||||
[LSQVER_ID24] = "FF000018",
|
||||
[LSQVER_ID25] = "FF000019",
|
||||
[LSQVER_VERNEG] = "FAFAFAFA",
|
||||
};
|
||||
|
||||
|
|
|
@ -706,6 +706,7 @@ http_client_on_read (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
|
|||
s_stat_downloaded_bytes > client_ctx->hcc_retire_cid_after_nbytes)
|
||||
{
|
||||
lsquic_conn_retire_cid(lsquic_stream_conn(stream));
|
||||
client_ctx->hcc_retire_cid_after_nbytes = 0;
|
||||
break;
|
||||
}
|
||||
if (!g_header_bypass && !(st_h->sh_flags & PROCESSED_HEADERS))
|
||||
|
@ -850,6 +851,7 @@ usage (const char *prog)
|
|||
" -T FILE Print stats to FILE. If FILE is -, print stats to stdout.\n"
|
||||
" -q FILE QIF mode: issue requests from the QIF file and validate\n"
|
||||
" server responses.\n"
|
||||
" -e TOKEN Hexadecimal string representing resume token.\n"
|
||||
, prog);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ prog_print_common_options (const struct prog *prog, FILE *out)
|
|||
" If no -s option is given, 0.0.0.0:12345 address\n"
|
||||
" is used.\n"
|
||||
#if LSQUIC_DONTFRAG_SUPPORTED
|
||||
" -D Set `do not fragment' flag on outgoing UDP packets\n"
|
||||
" -D Do not set `do not fragment' flag on outgoing UDP packets\n"
|
||||
#endif
|
||||
" -z BYTES Maximum size of outgoing UDP packets. The default is 1370\n"
|
||||
" bytes for IPv4 socket and 1350 bytes for IPv6 socket\n"
|
||||
|
@ -226,7 +226,7 @@ prog_set_opt (struct prog *prog, int opt, const char *arg)
|
|||
struct service_port *sport = TAILQ_LAST(prog->prog_sports, sport_head);
|
||||
if (!sport)
|
||||
sport = &prog->prog_dummy_sport;
|
||||
sport->sp_flags |= SPORT_DONT_FRAGMENT;
|
||||
sport->sp_flags |= SPORT_FRAGMENT_OK;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,7 @@ static int
|
|||
select_alpn (SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
||||
const unsigned char *in, unsigned int inlen, void *arg)
|
||||
{
|
||||
const unsigned char alpn[] = "\x5h3-23\x5h3-24";
|
||||
const unsigned char alpn[] = "\x5h3-24\x5h3-25";
|
||||
int r;
|
||||
|
||||
r = SSL_select_next_proto((unsigned char **) out, outlen, in, inlen,
|
||||
|
|
|
@ -922,7 +922,7 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
|
|||
#endif
|
||||
|
||||
#if LSQUIC_DONTFRAG_SUPPORTED
|
||||
if (sport->sp_flags & SPORT_DONT_FRAGMENT)
|
||||
if (!(sport->sp_flags & SPORT_FRAGMENT_OK))
|
||||
{
|
||||
if (AF_INET == sa_local->sa_family)
|
||||
{
|
||||
|
@ -1110,7 +1110,7 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine,
|
|||
#endif
|
||||
|
||||
#if LSQUIC_DONTFRAG_SUPPORTED
|
||||
if (sport->sp_flags & SPORT_DONT_FRAGMENT)
|
||||
if (!(sport->sp_flags & SPORT_FRAGMENT_OK))
|
||||
{
|
||||
if (AF_INET == sa_local->sa_family)
|
||||
{
|
||||
|
@ -1811,6 +1811,11 @@ set_engine_option (struct lsquic_engine_settings *settings,
|
|||
settings->es_idle_conn_to = atoi(val);
|
||||
return 0;
|
||||
}
|
||||
if (0 == strncmp(name, "idle_timeout", 12))
|
||||
{
|
||||
settings->es_idle_timeout = atoi(val);
|
||||
return 0;
|
||||
}
|
||||
if (0 == strncmp(name, "silent_close", 12))
|
||||
{
|
||||
settings->es_silent_close = atoi(val);
|
||||
|
|
|
@ -23,7 +23,7 @@ struct reader_ctx;
|
|||
enum sport_flags
|
||||
{
|
||||
#if LSQUIC_DONTFRAG_SUPPORTED
|
||||
SPORT_DONT_FRAGMENT = (1 << 0),
|
||||
SPORT_FRAGMENT_OK = (1 << 0),
|
||||
#endif
|
||||
SPORT_SET_SNDBUF = (1 << 1), /* SO_SNDBUF */
|
||||
SPORT_SET_RCVBUF = (1 << 2), /* SO_RCVBUF */
|
||||
|
|
|
@ -179,7 +179,7 @@ run_test (const struct test *test)
|
|||
size_t sz;
|
||||
unsigned char buf[0x1000];
|
||||
|
||||
pf = select_pf_by_ver(LSQVER_ID23);
|
||||
pf = select_pf_by_ver(LSQVER_ID24);
|
||||
if (!test->skip_gen)
|
||||
{
|
||||
rechist.acki = &test->acki;
|
||||
|
|
|
@ -33,7 +33,7 @@ struct test {
|
|||
static const struct test tests[] = {
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID23),
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.offset = 0,
|
||||
.data_sz = 10,
|
||||
.data = "0123456789",
|
||||
|
@ -49,7 +49,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID23),
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.offset = 500,
|
||||
.data_sz = 10,
|
||||
.data = "0123456789",
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include "lsquic_hq.h"
|
||||
#include "lsquic_data_in_if.h"
|
||||
|
||||
static const struct parse_funcs *g_pf = select_pf_by_ver(LSQVER_ID23);
|
||||
static const struct parse_funcs *g_pf = select_pf_by_ver(LSQVER_ID24);
|
||||
|
||||
struct test_ctl_settings
|
||||
{
|
||||
|
@ -297,7 +297,7 @@ init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
|||
memset(tobjs, 0, sizeof(*tobjs));
|
||||
LSCONN_INITIALIZE(&tobjs->lconn);
|
||||
tobjs->lconn.cn_pf = g_pf;
|
||||
tobjs->lconn.cn_version = LSQVER_ID23;
|
||||
tobjs->lconn.cn_version = LSQVER_ID24;
|
||||
tobjs->lconn.cn_esf_c = &lsquic_enc_session_common_ietf_v1;
|
||||
network_path.np_pack_size = packet_sz;
|
||||
tobjs->lconn.cn_if = &our_conn_if;
|
||||
|
|
|
@ -158,8 +158,8 @@ init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
|||
int s;
|
||||
memset(tobjs, 0, sizeof(*tobjs));
|
||||
LSCONN_INITIALIZE(&tobjs->lconn);
|
||||
tobjs->lconn.cn_pf = select_pf_by_ver(LSQVER_ID23);
|
||||
tobjs->lconn.cn_version = LSQVER_ID23;
|
||||
tobjs->lconn.cn_pf = select_pf_by_ver(LSQVER_ID24);
|
||||
tobjs->lconn.cn_version = LSQVER_ID24;
|
||||
tobjs->lconn.cn_esf_c = &lsquic_enc_session_common_ietf_v1;
|
||||
network_path.np_pack_size = IQUIC_MAX_IPv4_PACKET_SZ;
|
||||
tobjs->lconn.cn_if = &our_conn_if;
|
||||
|
|
|
@ -325,7 +325,7 @@ init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
|||
LSCONN_INITIALIZE(&tobjs->lconn);
|
||||
tobjs->lconn.cn_pf = pf ? pf : g_pf;
|
||||
tobjs->lconn.cn_version = tobjs->lconn.cn_pf == &lsquic_parse_funcs_ietf_v1 ?
|
||||
LSQVER_ID23 : LSQVER_043;
|
||||
LSQVER_ID24 : LSQVER_043;
|
||||
tobjs->lconn.cn_esf_c = &lsquic_enc_session_common_gquic_1;
|
||||
network_path.np_pack_size = 1370;
|
||||
tobjs->lconn.cn_if = &our_conn_if;
|
||||
|
@ -2200,7 +2200,7 @@ test_changing_pack_size (void)
|
|||
enum lsquic_version versions_to_test[3] =
|
||||
{
|
||||
LSQVER_046,
|
||||
LSQVER_ID23,
|
||||
LSQVER_ID24,
|
||||
};
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
|
@ -3130,7 +3130,7 @@ main (int argc, char **argv)
|
|||
|
||||
/* Redo some tests using crypto streams and frames */
|
||||
g_use_crypto_ctor = 1;
|
||||
g_pf = select_pf_by_ver(LSQVER_ID23);
|
||||
g_pf = select_pf_by_ver(LSQVER_ID24);
|
||||
main_test_packetization();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -279,7 +279,7 @@ static const struct test tests[] = {
|
|||
*/
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID23),
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.fin = { 0, 1, },
|
||||
.offset = 0x0807060504030201UL,
|
||||
.stream_id = 0x210,
|
||||
|
@ -299,7 +299,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID23),
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.fin = { 0, 0, },
|
||||
.offset = 0,
|
||||
.stream_id = 0x210,
|
||||
|
@ -318,7 +318,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID23),
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.fin = { 0, 0, },
|
||||
.offset = 0,
|
||||
.stream_id = 0x21,
|
||||
|
@ -336,7 +336,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID23),
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.fin = { 0, 0, },
|
||||
.offset = 0x0807060504030201UL,
|
||||
.stream_id = 0x210,
|
||||
|
@ -356,7 +356,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID23),
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.fin = { 1, 0, },
|
||||
.offset = 0x0807060504030201UL,
|
||||
.stream_id = 0x210,
|
||||
|
@ -374,7 +374,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID23),
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.fin = { 1, 0, },
|
||||
.offset = 0x0807060504030201UL,
|
||||
.stream_id = 0x210,
|
||||
|
|
|
@ -243,7 +243,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Balls to the wall: every possible bit is set",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 1<<0,
|
||||
0x41, 0x23, /* Stream ID */
|
||||
|
@ -262,7 +262,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Balls to the wall #2: every possible bit is set except FIN",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -281,7 +281,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Data length is zero",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 0<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -299,7 +299,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Sanity check: what happens when data length is zero #1",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -318,7 +318,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Sanity check: what happens when data length is zero #2",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -337,7 +337,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Sanity check: what happens when data length is zero #3",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 0<<2 | 1<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -355,7 +355,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Sanity check: what happens when data length is zero #3",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 1<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -374,7 +374,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Check data bounds #1",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 1<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -393,7 +393,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Check data bounds #2",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID23),
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 1<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
|
|
@ -56,7 +56,7 @@ static const struct trapa_test tests[] =
|
|||
.tp_flags = 0,
|
||||
.tp_init_max_stream_data_bidi_local = 0x12348877,
|
||||
.tp_init_max_data = 0xAABB,
|
||||
.tp_idle_timeout = 10 * 1000,
|
||||
.tp_max_idle_timeout = 10 * 1000,
|
||||
.tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY,
|
||||
.tp_active_connection_id_limit = 7,
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue