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:
Dmitri Tikhonov 2020-01-28 09:35:09 -05:00
parent fb96f4dd43
commit 9fc120419d
51 changed files with 8220 additions and 258 deletions

View file

@ -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

View file

@ -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 \

View file

@ -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",
};

View file

@ -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,
};

View file

@ -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,

View file

@ -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);

View file

@ -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,
};

View file

@ -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 )

View file

@ -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]))
{

View file

@ -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);
}
}

View file

@ -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

View file

@ -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 */

File diff suppressed because it is too large Load diff

View file

@ -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);
}

View file

@ -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,

View file

@ -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

View file

@ -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;

View file

@ -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];

View file

@ -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 */

View file

@ -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 */

View file

@ -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))

View file

@ -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 */

View file

@ -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,
};

View file

@ -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,
};

View file

@ -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,
};

View file

@ -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

View file

@ -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,
};

View file

@ -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,
};

View file

@ -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,

View file

@ -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));
}

View file

@ -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

View file

@ -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
{

View file

@ -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);

View file

@ -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, \

View file

@ -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",
};