Release 2.18.0

- [API] Rename "0-RTT" to "session resumption." In IETF QUIC, "0-RTT"
  always refers to early data, meaning a request that the server can
  reply to in the very first return flight.  A more appropriate name
  for what we support on the client site is "session resumption," which
  is standard TLS terminology.  Later, when we add support for 0-RTT
  (early data), we can use the 0-RTT terminology again, this time in
  proper context.
- [BUGFIX] Do not set certificate callback if ea_lookup_cert is NULL.
- [BUGFIX] Make connection tickable when it's marked as closed.
- [BUGFIX] Fail certificate lookup if SNI is not present in HTTP mode.
- Several documentation fixes and improvements.
- Minor code cleanup.
This commit is contained in:
Dmitri Tikhonov 2020-07-06 17:35:21 -04:00
parent da99665b1c
commit 7483dee074
26 changed files with 359 additions and 273 deletions

View file

@ -110,8 +110,8 @@ hsk_client_on_read (lsquic_stream_t *stream, struct lsquic_stream_ctx *sh)
if (c_hsk->lconn->cn_esf.g->esf_is_hsk_done(c_hsk->lconn->cn_enc_session))
{
LSQ_DEBUG("handshake is successful, inform connection");
status = (c_hsk->lconn->cn_esf_c->esf_did_zero_rtt_succeed(
c_hsk->lconn->cn_enc_session)) ? LSQ_HSK_0RTT_OK : LSQ_HSK_OK;
status = (c_hsk->lconn->cn_esf_c->esf_did_sess_resume_succeed(
c_hsk->lconn->cn_enc_session)) ? LSQ_HSK_RESUMED_OK : LSQ_HSK_OK;
c_hsk->lconn->cn_if->ci_hsk_done(c_hsk->lconn, status);
}
else

View file

@ -115,10 +115,10 @@ struct enc_session_funcs_common
(*esf_verify_reset_token) (enc_session_t *, const unsigned char *, size_t);
int
(*esf_did_zero_rtt_succeed) (enc_session_t *);
(*esf_did_sess_resume_succeed) (enc_session_t *);
int
(*esf_is_zero_rtt_enabled) (enc_session_t *);
(*esf_is_sess_resume_enabled) (enc_session_t *);
void
(*esf_set_conn) (enc_session_t *, struct lsquic_conn *);
@ -231,11 +231,12 @@ struct enc_session_funcs_gquic
size_t
(*esf_mem_used)(enc_session_t *);
/* Zero-rtt serialization needs the knowledge of the QUIC version, that's
* why there is a separate method for thus. Plus, we want to be able to
* call it after the "handshake is done" callback is called.
/* Session resumption serialization needs the knowledge of the QUIC
* version, that's why there is a separate method for thus. Plus, we
* want to be able to call it after the "handshake is done" callback
* is called.
*/
void (*esf_maybe_dispatch_zero_rtt) (enc_session_t *,
void (*esf_maybe_dispatch_sess_resume) (enc_session_t *,
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t));
void (*esf_reset_cid) (enc_session_t *, const lsquic_cid_t *);
@ -361,7 +362,7 @@ extern const struct lsquic_stream_if lsquic_mini_cry_sm_if;
#define ALERT_NO_APPLICATION_PROTOCOL 120
enum lsquic_version
lsquic_zero_rtt_version (const unsigned char *, size_t);
lsquic_sess_resume_version (const unsigned char *, size_t);
/* This is seems to be true for all of the ciphers used by IETF QUIC.
* XXX: Perhaps add a check?

View file

@ -20,7 +20,7 @@ const char *const lsquic_enclev2str[] =
enum lsquic_version
lsquic_zero_rtt_version (const unsigned char *buf, size_t bufsz)
lsquic_sess_resume_version (const unsigned char *buf, size_t bufsz)
{
lsquic_ver_tag_t tag;

View file

@ -247,8 +247,8 @@ struct enc_sess_iquic
char *esi_sni_bypass;
#endif
const unsigned char *esi_alpn;
unsigned char *esi_zero_rtt_buf;
size_t esi_zero_rtt_sz;
unsigned char *esi_sess_resume_buf;
size_t esi_sess_resume_sz;
/* Need MD and AEAD for key rotation */
const EVP_MD *esi_md;
const EVP_AEAD *esi_aead;
@ -649,7 +649,7 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
* uint8_t trapa_buf[ trapa_size ]
*/
#define ZERO_RTT_VERSION 1
#define SESS_RESUME_VERSION 1
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define READ_NUM(var_, ptr_) do { \
@ -674,31 +674,33 @@ maybe_create_SSL_SESSION (struct enc_sess_iquic *enc_sess,
uint32_t rtt_ver, ticket_sz, trapa_sz;
const unsigned char *ticket_buf, *trapa_buf, *p;
const unsigned char *const end
= enc_sess->esi_zero_rtt_buf + enc_sess->esi_zero_rtt_sz;
= enc_sess->esi_sess_resume_buf + enc_sess->esi_sess_resume_sz;
if (enc_sess->esi_zero_rtt_sz
if (enc_sess->esi_sess_resume_sz
< sizeof(ver_tag) + sizeof(rtt_ver) + sizeof(ticket_sz))
{
LSQ_DEBUG("rtt buf too short");
return NULL;
}
p = enc_sess->esi_zero_rtt_buf;
p = enc_sess->esi_sess_resume_buf;
memcpy(&ver_tag, p, sizeof(ver_tag));
p += sizeof(ver_tag);
quic_ver = lsquic_tag2ver(ver_tag);
if (quic_ver != enc_sess->esi_ver_neg->vn_ver)
{
LSQ_DEBUG("negotiated version %s does not match that in the zero-rtt "
"info buffer", lsquic_ver2str[enc_sess->esi_ver_neg->vn_ver]);
LSQ_DEBUG("negotiated version %s does not match that in the session "
"resumption nfo buffer",
lsquic_ver2str[enc_sess->esi_ver_neg->vn_ver]);
return NULL;
}
READ_NUM(rtt_ver, p);
if (rtt_ver != ZERO_RTT_VERSION)
if (rtt_ver != SESS_RESUME_VERSION)
{
LSQ_DEBUG("cannot use zero-rtt buffer: encoded using %"PRIu32", "
"while current version is %u", rtt_ver, ZERO_RTT_VERSION);
LSQ_DEBUG("cannot use session resumption buffer: encoded using "
"%"PRIu32", while current version is %u",
rtt_ver, SESS_RESUME_VERSION);
return NULL;
}
@ -759,7 +761,7 @@ iquic_esfi_create_client (const char *hostname,
struct lsquic_engine_public *enpub, struct lsquic_conn *lconn,
const lsquic_cid_t *dcid, const struct ver_neg *ver_neg,
void *crypto_streams[4], const struct crypto_stream_if *cryst_if,
const unsigned char *zero_rtt, size_t zero_rtt_sz,
const unsigned char *sess_resume, size_t sess_resume_sz,
struct lsquic_alarmset *alset, unsigned max_streams_uni)
{
struct enc_sess_iquic *enc_sess;
@ -814,24 +816,24 @@ iquic_esfi_create_client (const char *hostname,
/* Have to wait until the call to init_client() -- this is when the
* result of version negotiation is known.
*/
if (zero_rtt && zero_rtt_sz)
if (sess_resume && sess_resume_sz)
{
enc_sess->esi_zero_rtt_buf = malloc(zero_rtt_sz);
if (enc_sess->esi_zero_rtt_buf)
enc_sess->esi_sess_resume_buf = malloc(sess_resume_sz);
if (enc_sess->esi_sess_resume_buf)
{
memcpy(enc_sess->esi_zero_rtt_buf, zero_rtt, zero_rtt_sz);
enc_sess->esi_zero_rtt_sz = zero_rtt_sz;
memcpy(enc_sess->esi_sess_resume_buf, sess_resume, sess_resume_sz);
enc_sess->esi_sess_resume_sz = sess_resume_sz;
}
else
enc_sess->esi_zero_rtt_sz = 0;
enc_sess->esi_sess_resume_sz = 0;
}
else
{
enc_sess->esi_zero_rtt_buf = NULL;
enc_sess->esi_zero_rtt_sz = 0;
enc_sess->esi_sess_resume_buf = NULL;
enc_sess->esi_sess_resume_sz = 0;
}
if (enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info)
if (enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info)
enc_sess->esi_flags |= ESI_WANT_TICKET;
enc_sess->esi_alset = alset;
lsquic_alarmset_init_alarm(enc_sess->esi_alset, AL_SESS_TICKET,
@ -1145,10 +1147,14 @@ iquic_lookup_cert (SSL *ssl, void *arg)
#endif
if (!server_name)
{
LSQ_DEBUG("cert lookup: server name is not set");
/* SNI is required in HTTP/3 */
if (enc_sess->esi_enpub->enp_flags & ENPUB_HTTP)
return 1;
{
LSQ_DEBUG("SNI is not set, but is required in HTTP/3: "
"fail certificate lookup");
return 0;
}
else
LSQ_DEBUG("cert lookup: server name is not set");
}
path = enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
@ -1268,7 +1274,8 @@ iquic_esfi_init_server (enc_session_t *enc_session_p)
}
SSL_clear_options(enc_sess->esi_ssl, SSL_OP_NO_TLSv1_3);
SSL_set_cert_cb(enc_sess->esi_ssl, iquic_lookup_cert, enc_sess);
if (enc_sess->esi_enpub->enp_lookup_cert)
SSL_set_cert_cb(enc_sess->esi_ssl, iquic_lookup_cert, enc_sess);
SSL_set_ex_data(enc_sess->esi_ssl, s_idx, enc_sess);
SSL_set_accept_state(enc_sess->esi_ssl);
LSQ_DEBUG("initialized server enc session");
@ -1305,13 +1312,14 @@ iquic_new_session_cb (SSL *ssl, SSL_SESSION *session)
size_t trapa_sz, buf_sz;
enc_sess = SSL_get_ex_data(ssl, s_idx);
assert(enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info);
assert(enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info);
SSL_get_peer_quic_transport_params(enc_sess->esi_ssl, &trapa_buf,
&trapa_sz);
if (!(trapa_buf + trapa_sz))
{
LSQ_WARN("no transport parameters: cannot generate zero-rtt info");
LSQ_WARN("no transport parameters: cannot generate session "
"resumption info");
return 0;
}
if (trapa_sz > UINT32_MAX)
@ -1347,7 +1355,7 @@ iquic_new_session_cb (SSL *ssl, SSL_SESSION *session)
memcpy(p, &tag, sizeof(tag));
p += sizeof(tag);
WRITE_NUM(num, ZERO_RTT_VERSION, p);
WRITE_NUM(num, SESS_RESUME_VERSION, p);
WRITE_NUM(num, ticket_sz, p);
memcpy(p, ticket_buf, ticket_sz);
p += ticket_sz;
@ -1358,9 +1366,9 @@ iquic_new_session_cb (SSL *ssl, SSL_SESSION *session)
assert(buf + buf_sz == p);
OPENSSL_free(ticket_buf);
LSQ_DEBUG("generated %zu bytes of zero-rtt buffer", buf_sz);
LSQ_DEBUG("generated %zu bytes of session resumption buffer", buf_sz);
enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info(enc_sess->esi_conn,
enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info(enc_sess->esi_conn,
buf, buf_sz);
free(buf);
enc_sess->esi_flags &= ~ESI_WANT_TICKET;
@ -1410,7 +1418,7 @@ init_client (struct enc_sess_iquic *const enc_sess)
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
SSL_CTX_set_default_verify_paths(ssl_ctx);
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT);
if (enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info)
if (enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info)
SSL_CTX_sess_set_new_cb(ssl_ctx, iquic_new_session_cb);
if (enc_sess->esi_enpub->enp_kli)
SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
@ -1465,7 +1473,7 @@ init_client (struct enc_sess_iquic *const enc_sess)
}
free(enc_sess->esi_hostname);
enc_sess->esi_hostname = NULL;
if (enc_sess->esi_zero_rtt_buf)
if (enc_sess->esi_sess_resume_buf)
{
ssl_session = maybe_create_SSL_SESSION(enc_sess, ssl_ctx);
if (ssl_session)
@ -1744,7 +1752,7 @@ iquic_esfi_handshake (struct enc_sess_iquic *enc_sess)
return IHS_WANT_WRITE;
case SSL_ERROR_EARLY_DATA_REJECTED:
LSQ_DEBUG("early data rejected");
hsk_status = LSQ_HSK_0RTT_FAIL;
hsk_status = LSQ_HSK_RESUMED_FAIL;
goto err;
/* fall through */
default:
@ -1767,14 +1775,14 @@ iquic_esfi_handshake (struct enc_sess_iquic *enc_sess)
hsk_status = LSQ_HSK_OK;
LSQ_DEBUG("handshake reported complete");
EV_LOG_HSK_COMPLETED(LSQUIC_LOG_CONN_ID);
/* The ESI_USE_SSL_TICKET flag indicates if the client attempted 0-RTT.
* If the handshake is complete, and the client attempted 0-RTT, it
* must have succeeded.
/* The ESI_USE_SSL_TICKET flag indicates if the client attempted session
* resumption. If the handshake is complete, and the client attempted
* session resumption, it must have succeeded.
*/
if (enc_sess->esi_flags & ESI_USE_SSL_TICKET)
{
hsk_status = LSQ_HSK_0RTT_OK;
EV_LOG_ZERO_RTT(LSQUIC_LOG_CONN_ID);
hsk_status = LSQ_HSK_RESUMED_OK;
EV_LOG_SESSION_RESUMPTION(LSQUIC_LOG_CONN_ID);
}
if (0 != maybe_get_peer_transport_params(enc_sess))
@ -1844,7 +1852,7 @@ iquic_esfi_destroy (enc_session_t *enc_session_p)
free_handshake_keys(enc_sess);
cleanup_hp(&enc_sess->esi_hp);
free(enc_sess->esi_zero_rtt_buf);
free(enc_sess->esi_sess_resume_buf);
free(enc_sess->esi_hostname);
free(enc_sess);
}
@ -2407,10 +2415,10 @@ iquic_esf_alg_keysize (enc_session_t *enc_session_p)
static int
iquic_esf_zero_rtt_enabled (enc_session_t *enc_session_p)
iquic_esf_sess_resume_enabled (enc_session_t *enc_session_p)
{
struct enc_sess_iquic *const enc_sess = enc_session_p;
return enc_sess->esi_zero_rtt_buf != NULL;
return enc_sess->esi_sess_resume_buf != NULL;
}
@ -2555,7 +2563,7 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1 =
.esf_cipher = iquic_esf_cipher,
.esf_keysize = iquic_esf_keysize,
.esf_alg_keysize = iquic_esf_alg_keysize,
.esf_is_zero_rtt_enabled = iquic_esf_zero_rtt_enabled,
.esf_is_sess_resume_enabled = iquic_esf_sess_resume_enabled,
.esf_set_conn = iquic_esf_set_conn,
};
@ -2573,7 +2581,7 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1_no_flush
.esf_cipher = iquic_esf_cipher,
.esf_keysize = iquic_esf_keysize,
.esf_alg_keysize = iquic_esf_alg_keysize,
.esf_is_zero_rtt_enabled = iquic_esf_zero_rtt_enabled,
.esf_is_sess_resume_enabled = iquic_esf_sess_resume_enabled,
.esf_set_conn = iquic_esf_set_conn,
};

View file

@ -1580,7 +1580,7 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version,
const struct sockaddr *peer_sa,
void *peer_ctx, lsquic_conn_ctx_t *conn_ctx,
const char *hostname, unsigned short max_packet_size,
const unsigned char *zero_rtt, size_t zero_rtt_len,
const unsigned char *sess_resume, size_t sess_resume_len,
const unsigned char *token, size_t token_sz)
{
lsquic_conn_t *conn;
@ -1606,14 +1606,14 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version,
return NULL;
flags = engine->flags & (ENG_SERVER|ENG_HTTP);
is_ipv4 = peer_sa->sa_family == AF_INET;
if (zero_rtt && zero_rtt_len)
if (sess_resume && sess_resume_len)
{
version = lsquic_zero_rtt_version(zero_rtt, zero_rtt_len);
version = lsquic_sess_resume_version(sess_resume, sess_resume_len);
if (version >= N_LSQVER)
{
LSQ_INFO("zero-rtt version is bad, won't use");
zero_rtt = NULL;
zero_rtt_len = 0;
LSQ_INFO("session resumption version is bad, won't use");
sess_resume = NULL;
sess_resume_len = 0;
}
}
if (version >= N_LSQVER)
@ -1627,11 +1627,11 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version 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);
is_ipv4, sess_resume, sess_resume_len, token, token_sz);
else
conn = lsquic_gquic_full_conn_client_new(&engine->pub, versions,
flags, hostname, max_packet_size, is_ipv4,
zero_rtt, zero_rtt_len);
sess_resume, sess_resume_len);
if (!conn)
goto err;
EV_LOG_CREATE_CONN(lsquic_conn_log_cid(conn), local_sa, peer_sa);

View file

@ -554,9 +554,9 @@ lsquic_ev_log_hsk_completed (const lsquic_cid_t *cid)
void
lsquic_ev_log_zero_rtt (const lsquic_cid_t *cid)
lsquic_ev_log_sess_resume (const lsquic_cid_t *cid)
{
LCID("zero_rtt successful");
LCID("sess_resume successful");
}

View file

@ -311,13 +311,13 @@ lsquic_ev_log_hsk_completed (const lsquic_cid_t *);
void
lsquic_ev_log_zero_rtt (const lsquic_cid_t *);
lsquic_ev_log_sess_resume (const lsquic_cid_t *);
#define EV_LOG_ZERO_RTT(...) do { \
#define EV_LOG_SESSION_RESUMPTION(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_zero_rtt(__VA_ARGS__); \
lsquic_ev_log_sess_resume(__VA_ARGS__); \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_QLOG)) \
lsquic_qlog_zero_rtt(__VA_ARGS__); \
lsquic_qlog_sess_resume(__VA_ARGS__); \
} while (0)
void

View file

@ -717,21 +717,21 @@ lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *enpub,
unsigned versions, unsigned flags,
const char *hostname, unsigned short max_packet_size,
int is_ipv4,
const unsigned char *zero_rtt, size_t zero_rtt_len)
const unsigned char *sess_resume, size_t sess_resume_len)
{
struct full_conn *conn;
enum lsquic_version version, zero_rtt_version;
enum lsquic_version version, sess_resume_version;
lsquic_cid_t cid;
const struct enc_session_funcs_gquic *esf_g;
versions &= (~LSQUIC_IETF_VERSIONS & LSQUIC_SUPPORTED_VERSIONS);
assert(versions);
version = highest_bit_set(versions);
if (zero_rtt)
if (sess_resume)
{
zero_rtt_version = lsquic_zero_rtt_version(zero_rtt, zero_rtt_len);
if (zero_rtt_version < N_LSQVER && ((1 << zero_rtt_version) & versions))
version = zero_rtt_version;
sess_resume_version = lsquic_sess_resume_version(sess_resume, sess_resume_len);
if (sess_resume_version < N_LSQVER && ((1 << sess_resume_version) & versions))
version = sess_resume_version;
}
esf_g = select_esf_gquic_by_ver(version);
lsquic_generate_cid_gquic(&cid);
@ -751,7 +751,7 @@ lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *enpub,
conn->fc_conn.cn_esf.g = esf_g;
conn->fc_conn.cn_enc_session =
conn->fc_conn.cn_esf.g->esf_create_client(&conn->fc_conn, hostname,
cid, conn->fc_enpub, zero_rtt, zero_rtt_len);
cid, conn->fc_enpub, sess_resume, sess_resume_len);
if (!conn->fc_conn.cn_enc_session)
{
LSQ_WARN("could not create enc session: %s", strerror(errno));
@ -1368,10 +1368,10 @@ full_conn_ci_n_avail_streams (const lsquic_conn_t *lconn)
static int
handshake_done_or_doing_zero_rtt (const struct full_conn *conn)
handshake_done_or_doing_sess_resume (const struct full_conn *conn)
{
return (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|| conn->fc_conn.cn_esf_c->esf_is_zero_rtt_enabled(
|| conn->fc_conn.cn_esf_c->esf_is_sess_resume_enabled(
conn->fc_conn.cn_enc_session);
}
@ -1380,7 +1380,7 @@ static void
full_conn_ci_make_stream (struct lsquic_conn *lconn)
{
struct full_conn *conn = (struct full_conn *) lconn;
if (handshake_done_or_doing_zero_rtt(conn)
if (handshake_done_or_doing_sess_resume(conn)
&& full_conn_ci_n_avail_streams(lconn) > 0)
{
if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW))
@ -3463,7 +3463,7 @@ full_conn_ci_tick (lsquic_conn_t *lconn, lsquic_time_t now)
}
lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 0);
if (!handshake_done_or_doing_zero_rtt(conn))
if (!handshake_done_or_doing_sess_resume(conn))
{
process_hsk_stream_write_events(conn);
goto end_write;
@ -3639,12 +3639,12 @@ full_conn_ci_hsk_done (lsquic_conn_t *lconn, enum lsquic_hsk_status status)
lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE);
switch (status)
{
case LSQ_HSK_0RTT_FAIL:
case LSQ_HSK_RESUMED_FAIL:
case LSQ_HSK_FAIL:
conn->fc_flags |= FC_HSK_FAILED;
break;
case LSQ_HSK_OK:
case LSQ_HSK_0RTT_OK:
case LSQ_HSK_RESUMED_OK:
if (0 == apply_peer_settings(conn))
{
if (conn->fc_flags & FC_HTTP)
@ -3658,12 +3658,12 @@ full_conn_ci_hsk_done (lsquic_conn_t *lconn, enum lsquic_hsk_status status)
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done)
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done(lconn,
status);
if (status == LSQ_HSK_OK || status == LSQ_HSK_0RTT_OK)
if (status == LSQ_HSK_OK || status == LSQ_HSK_RESUMED_OK)
{
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_zero_rtt_info)
conn->fc_conn.cn_esf.g->esf_maybe_dispatch_zero_rtt(
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_sess_resume_info)
conn->fc_conn.cn_esf.g->esf_maybe_dispatch_sess_resume(
conn->fc_conn.cn_enc_session,
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_zero_rtt_info);
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_sess_resume_info);
if (conn->fc_n_delayed_streams)
create_delayed_streams(conn);
if (!(conn->fc_flags & FC_SERVER))
@ -3721,6 +3721,7 @@ full_conn_ci_close (struct lsquic_conn *lconn)
conn->fc_flags |= FC_CLOSING;
if (!(conn->fc_flags & FC_GOAWAY_SENT))
conn->fc_flags |= FC_SEND_GOAWAY;
lsquic_engine_add_conn_to_tickable(conn->fc_enpub, lconn);
}
}
@ -4204,7 +4205,7 @@ full_conn_ci_is_tickable (lsquic_conn_t *lconn)
LSQ_DEBUG("tickable: there are sending streams");
goto check_can_send;
}
if (handshake_done_or_doing_zero_rtt(conn))
if (handshake_done_or_doing_sess_resume(conn))
{
TAILQ_FOREACH(stream, &conn->fc_pub.write_streams,
next_write_stream)
@ -4302,7 +4303,7 @@ lsquic_gquic_full_conn_srej (struct lsquic_conn *lconn)
struct lsquic_stream *stream;
enum lsquic_version version;
if (lconn->cn_esf_c->esf_is_zero_rtt_enabled(conn->fc_conn.cn_enc_session))
if (lconn->cn_esf_c->esf_is_sess_resume_enabled(conn->fc_conn.cn_enc_session))
{
/* We need to do this because we do not clean up any data that may
* have been already sent. This is left an optimization for the
@ -4310,7 +4311,7 @@ lsquic_gquic_full_conn_srej (struct lsquic_conn *lconn)
*/
LSQ_DEBUG("received SREJ when 0RTT was on: fail handshake and let "
"caller retry");
full_conn_ci_hsk_done(lconn, LSQ_HSK_0RTT_FAIL);
full_conn_ci_hsk_done(lconn, LSQ_HSK_RESUMED_FAIL);
return -1;
}

View file

@ -11,14 +11,14 @@ lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *,
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 zero_rtt_len);
const unsigned char *sess_resume, size_t sess_resume_len);
struct lsquic_conn *
lsquic_ietf_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 *sess_resume, size_t,
const unsigned char *token, size_t);
typedef struct lsquic_conn *

View file

@ -1158,12 +1158,12 @@ struct lsquic_conn *
lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
unsigned versions, unsigned flags,
const char *hostname, unsigned short max_packet_size, int is_ipv4,
const unsigned char *zero_rtt, size_t zero_rtt_sz,
const unsigned char *sess_resume, size_t sess_resume_sz,
const unsigned char *token, size_t token_sz)
{
const struct enc_session_funcs_iquic *esfi;
struct ietf_full_conn *conn;
enum lsquic_version ver, zero_rtt_version;
enum lsquic_version ver, sess_resume_version;
lsquic_time_t now;
conn = calloc(1, sizeof(*conn));
@ -1181,11 +1181,11 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
assert(versions);
versions &= LSQUIC_IETF_VERSIONS;
ver = highest_bit_set(versions);
if (zero_rtt)
if (sess_resume)
{
zero_rtt_version = lsquic_zero_rtt_version(zero_rtt, zero_rtt_sz);
if (zero_rtt_version < N_LSQVER && ((1 << zero_rtt_version) & versions))
ver = zero_rtt_version;
sess_resume_version = lsquic_sess_resume_version(sess_resume, sess_resume_sz);
if (sess_resume_version < N_LSQVER && ((1 << sess_resume_version) & versions))
ver = sess_resume_version;
}
esfi = select_esf_iquic_by_ver(ver);
@ -1252,7 +1252,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
conn->ifc_enpub, &conn->ifc_conn, CUR_DCID(conn),
&conn->ifc_u.cli.ifcli_ver_neg,
(void **) conn->ifc_u.cli.crypto_streams, &crypto_stream_if,
zero_rtt, zero_rtt_sz, &conn->ifc_alset,
sess_resume, sess_resume_sz, &conn->ifc_alset,
conn->ifc_max_streams_in[SD_UNI]);
if (!conn->ifc_conn.cn_enc_session)
goto err2;
@ -2560,6 +2560,7 @@ ietf_full_conn_ci_close (struct lsquic_conn *lconn)
}
conn->ifc_flags |= IFC_CLOSING;
conn->ifc_send_flags |= SF_SEND_CONN_CLOSE;
lsquic_engine_add_conn_to_tickable(conn->ifc_enpub, lconn);
}
}
@ -3279,7 +3280,7 @@ ietf_full_conn_ci_hsk_done (struct lsquic_conn *lconn,
switch (status)
{
case LSQ_HSK_OK:
case LSQ_HSK_0RTT_OK:
case LSQ_HSK_RESUMED_OK:
if (0 == handshake_ok(lconn))
{
if (!(conn->ifc_flags & IFC_SERVER))
@ -3297,7 +3298,7 @@ ietf_full_conn_ci_hsk_done (struct lsquic_conn *lconn,
assert(0);
/* fall-through */
case LSQ_HSK_FAIL:
case LSQ_HSK_0RTT_FAIL:
case LSQ_HSK_RESUMED_FAIL:
handshake_failed(lconn);
break;
}
@ -7102,10 +7103,10 @@ ietf_full_conn_ci_n_avail_streams (const struct lsquic_conn *lconn)
static int
handshake_done_or_doing_zero_rtt (const struct ietf_full_conn *conn)
handshake_done_or_doing_sess_resume (const struct ietf_full_conn *conn)
{
return (conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|| conn->ifc_conn.cn_esf_c->esf_is_zero_rtt_enabled(
|| conn->ifc_conn.cn_esf_c->esf_is_sess_resume_enabled(
conn->ifc_conn.cn_enc_session);
}
@ -7115,7 +7116,7 @@ ietf_full_conn_ci_make_stream (struct lsquic_conn *lconn)
{
struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn;
if (handshake_done_or_doing_zero_rtt(conn)
if (handshake_done_or_doing_sess_resume(conn)
&& ietf_full_conn_ci_n_avail_streams(lconn) > 0)
{
if (0 != create_bidi_stream_out(conn))

View file

@ -201,7 +201,7 @@ typedef struct c_cert_item_st
} c_cert_item_t;
struct lsquic_zero_rtt_storage
struct lsquic_sess_resume_storage
{
uint32_t quic_version_tag;
uint32_t serializer_version;
@ -592,7 +592,7 @@ enum rtt_deserialize_return_type
#define RTT_SERIALIZER_VERSION (1 << 0)
static void
lsquic_enc_session_serialize_zero_rtt(struct lsquic_zero_rtt_storage *storage,
lsquic_enc_session_serialize_sess_resume(struct lsquic_sess_resume_storage *storage,
enum lsquic_version version,
const lsquic_session_cache_info_t *info,
const c_cert_item_t *cert_item)
@ -643,8 +643,8 @@ lsquic_enc_session_serialize_zero_rtt(struct lsquic_zero_rtt_storage *storage,
} while (0) \
static enum rtt_deserialize_return_type
lsquic_enc_session_deserialize_zero_rtt(
const struct lsquic_zero_rtt_storage *storage,
lsquic_enc_session_deserialize_sess_resume(
const struct lsquic_sess_resume_storage *storage,
size_t storage_size,
const struct lsquic_engine_settings *settings,
lsquic_session_cache_info_t *info,
@ -824,12 +824,12 @@ maybe_log_secrets (struct lsquic_enc_session *enc_session)
static enc_session_t *
lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
lsquic_cid_t cid, const struct lsquic_engine_public *enpub,
const unsigned char *zero_rtt, size_t zero_rtt_len)
const unsigned char *sess_resume, size_t sess_resume_len)
{
lsquic_session_cache_info_t *info;
struct lsquic_enc_session *enc_session;
c_cert_item_t *item;
const struct lsquic_zero_rtt_storage *zero_rtt_storage;
const struct lsquic_sess_resume_storage *sess_resume_storage;
if (!domain)
{
@ -849,7 +849,7 @@ lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
return NULL;
}
if (zero_rtt && zero_rtt_len > sizeof(struct lsquic_zero_rtt_storage))
if (sess_resume && sess_resume_len > sizeof(struct lsquic_sess_resume_storage))
{
item = calloc(1, sizeof(*item));
if (!item)
@ -858,22 +858,22 @@ lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
free(info);
return NULL;
}
zero_rtt_storage = (const struct lsquic_zero_rtt_storage *)zero_rtt;
switch (lsquic_enc_session_deserialize_zero_rtt(zero_rtt_storage,
zero_rtt_len,
sess_resume_storage = (const struct lsquic_sess_resume_storage *)sess_resume;
switch (lsquic_enc_session_deserialize_sess_resume(sess_resume_storage,
sess_resume_len,
&enpub->enp_settings,
info, item))
{
case RTT_DESERIALIZE_BAD_QUIC_VER:
LSQ_ERROR("provided zero_rtt has unsupported QUIC version");
LSQ_ERROR("provided sess_resume has unsupported QUIC version");
free(item);
break;
case RTT_DESERIALIZE_BAD_SERIAL_VER:
LSQ_ERROR("provided zero_rtt has bad serializer version");
LSQ_ERROR("provided sess_resume has bad serializer version");
free(item);
break;
case RTT_DESERIALIZE_BAD_CERT_SIZE:
LSQ_ERROR("provided zero_rtt has bad cert size");
LSQ_ERROR("provided sess_resume has bad cert size");
free(item);
break;
case RTT_DESERIALIZE_OK:
@ -2728,7 +2728,7 @@ lsquic_enc_session_handle_chlo_reply (enc_session_t *enc_session_p,
enc_session->hsk_state = HSK_COMPLETED;
EV_LOG_HSK_COMPLETED(&enc_session->cid);
if (!(enc_session->es_flags & ES_RECV_REJ))
EV_LOG_ZERO_RTT(&enc_session->cid);
EV_LOG_SESSION_RESUMPTION(&enc_session->cid);
break;
default:
ret = 1; /* XXX Why 1? */
@ -3599,7 +3599,7 @@ lsquic_enc_session_verify_reset_token (enc_session_t *enc_session_p,
static int
lsquic_enc_session_did_zero_rtt_succeed (enc_session_t *enc_session_p)
lsquic_enc_session_did_sess_resume_succeed (enc_session_t *enc_session_p)
{
struct lsquic_enc_session *const enc_session = enc_session_p;
return !(enc_session->es_flags & ES_RECV_REJ);
@ -3607,7 +3607,7 @@ lsquic_enc_session_did_zero_rtt_succeed (enc_session_t *enc_session_p)
static int
lsquic_enc_session_is_zero_rtt_enabled (enc_session_t *enc_session_p)
lsquic_enc_session_is_sess_resume_enabled (enc_session_t *enc_session_p)
{
struct lsquic_enc_session *const enc_session = enc_session_p;
return enc_session->info && enc_session->cert_item;
@ -3689,7 +3689,7 @@ lsquic_enc_session_get_server_cert_chain (enc_session_t *enc_session_p)
static void
maybe_dispatch_zero_rtt (enc_session_t *enc_session_p,
maybe_dispatch_sess_resume (enc_session_t *enc_session_p,
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t))
{
struct lsquic_enc_session *const enc_session = enc_session_p;
@ -3700,7 +3700,7 @@ maybe_dispatch_zero_rtt (enc_session_t *enc_session_p,
if (!(enc_session->info && enc_session->cert_item && cb))
{
LSQ_DEBUG("no zero-rtt information or callback is not set");
LSQ_DEBUG("no session resumption information or callback is not set");
return;
}
@ -3709,17 +3709,18 @@ maybe_dispatch_zero_rtt (enc_session_t *enc_session_p,
sz += sizeof(uint32_t);
sz += lsquic_str_len(&enc_session->cert_item->crts[i]);
}
sz += sizeof(struct lsquic_zero_rtt_storage);
sz += sizeof(struct lsquic_sess_resume_storage);
buf = malloc(sz);
if (!buf)
{
LSQ_WARN("malloc failed: cannot allocate %zu bytes for zero-rtt", sz);
LSQ_WARN("malloc failed: cannot allocate %zu bytes for session "
"resumption", sz);
return;
}
lsquic_enc_session_serialize_zero_rtt(
(struct lsquic_zero_rtt_storage *) buf, lconn->cn_version,
lsquic_enc_session_serialize_sess_resume(
(struct lsquic_sess_resume_storage *) buf, lconn->cn_version,
enc_session->info, enc_session->cert_item);
cb(lconn, buf, sz);
@ -3796,8 +3797,8 @@ struct enc_session_funcs_common lsquic_enc_session_common_gquic_1 =
.esf_tag_len = GQUIC_PACKET_HASH_SZ,
.esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
.esf_did_zero_rtt_succeed = lsquic_enc_session_did_zero_rtt_succeed,
.esf_is_zero_rtt_enabled = lsquic_enc_session_is_zero_rtt_enabled,
.esf_did_sess_resume_succeed = lsquic_enc_session_did_sess_resume_succeed,
.esf_is_sess_resume_enabled = lsquic_enc_session_is_sess_resume_enabled,
.esf_set_conn = gquic_esf_set_conn,
};
@ -4225,8 +4226,8 @@ struct enc_session_funcs_common lsquic_enc_session_common_gquic_2 =
.esf_alg_keysize = lsquic_enc_session_alg_keysize,
.esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
.esf_did_zero_rtt_succeed = lsquic_enc_session_did_zero_rtt_succeed,
.esf_is_zero_rtt_enabled = lsquic_enc_session_is_zero_rtt_enabled,
.esf_did_sess_resume_succeed = lsquic_enc_session_did_sess_resume_succeed,
.esf_is_sess_resume_enabled = lsquic_enc_session_is_sess_resume_enabled,
.esf_set_conn = gquic_esf_set_conn,
/* These are different from gquic_1: */
.esf_encrypt_packet = gquic2_esf_encrypt_packet,
@ -4266,7 +4267,7 @@ struct enc_session_funcs_gquic lsquic_enc_session_gquic_gquic_1 =
.esf_gen_chlo = lsquic_enc_session_gen_chlo,
.esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply,
.esf_mem_used = lsquic_enc_session_mem_used,
.esf_maybe_dispatch_zero_rtt = maybe_dispatch_zero_rtt,
.esf_maybe_dispatch_sess_resume = maybe_dispatch_sess_resume,
.esf_reset_cid = lsquic_enc_session_reset_cid,
};

View file

@ -111,6 +111,6 @@ enum hsk_failure_reason
};
enum lsquic_version
lsquic_zero_rtt_version (const unsigned char *, size_t);
lsquic_sess_resume_version (const unsigned char *, size_t);
#endif

View file

@ -590,7 +590,7 @@ ietf_mini_conn_ci_hsk_done (struct lsquic_conn *lconn,
switch (status)
{
case LSQ_HSK_OK:
case LSQ_HSK_0RTT_OK:
case LSQ_HSK_RESUMED_OK:
conn->imc_flags |= IMC_HSK_OK;
conn->imc_conn.cn_flags |= LSCONN_HANDSHAKE_DONE;
LSQ_DEBUG("handshake OK");

View file

@ -83,6 +83,7 @@ lsquic_qlog_create_connection (const lsquic_cid_t* cid,
lsquic_time_now(), ip_version, srcip, dstip, srcport, dstport);
}
#define QLOG_FRAME_DICT_PREFIX_COMMA ",{\"frame_type\":\""
#define QLOG_FRAME_DICT_PREFIX "{\"frame_type\":\""
#define QLOG_FRAME_DICT_SUFFIX "\"}"
@ -170,7 +171,7 @@ lsquic_qlog_hsk_completed (const lsquic_cid_t* cid)
void
lsquic_qlog_zero_rtt (const lsquic_cid_t* cid)
lsquic_qlog_sess_resume (const lsquic_cid_t* cid)
{
LCID("[%" PRIu64 ",\"RECOVERY\",\"RTT_UPDATE\",\"PACKET_RX\","
"{\"zero_rtt\":\"successful\"}]", lsquic_time_now());

View file

@ -80,7 +80,7 @@ void
lsquic_qlog_hsk_completed (const lsquic_cid_t *);
void
lsquic_qlog_zero_rtt (const lsquic_cid_t *);
lsquic_qlog_sess_resume (const lsquic_cid_t *);
void
lsquic_qlog_check_certs (const lsquic_cid_t *, const lsquic_str_t **, size_t);

View file

@ -412,7 +412,7 @@ lsquic_stream_destroy (lsquic_stream_t *);
* failure. The latter may be caused by flow control violation or
* invalid stream frame data, e.g. overlapping segments.
*
* Note that the caller does gives up control of `frame' no matter
* Note that the caller gives up control of `frame' no matter
* what this function returns.
*
* This data is read by the user using lsquic_stream_read() function.
@ -436,9 +436,6 @@ lsquic_stream_rst_in (lsquic_stream_t *, uint64_t offset, uint64_t error_code);
void
lsquic_stream_stop_sending_in (struct lsquic_stream *, uint64_t error_code);
ssize_t
lsquic_stream_read (lsquic_stream_t *stream, void *buf, size_t len);
uint64_t
lsquic_stream_read_offset (const lsquic_stream_t *stream);
@ -448,11 +445,6 @@ lsquic_stream_read_offset (const lsquic_stream_t *stream);
int
lsquic_stream_tosend_fin (const lsquic_stream_t *stream);
/* Data to be sent out to the network is written using lsquic_stream_write().
*/
ssize_t
lsquic_stream_write (lsquic_stream_t *stream, const void *buf, size_t len);
void
lsquic_stream_window_update (lsquic_stream_t *stream, uint64_t offset);

View file

@ -8,7 +8,7 @@
struct ver_neg {
unsigned vn_supp; /* Remaining options, including `vn_ver' */
enum lsquic_version vn_ver; /* If client, current version sent to server
* (zero_rtt version or highest supported);
* (sess_resume version or highest supported);
* if server, this is set to negotiated version.
*/
enum ver_neg_state {