mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.7.2
- [BUGFIX] Send controller: update scheduled bytes when DCID length changes (IETF client). - [BUGFIX] Drop alarm check from sanity test. It no longer works now that we use loss chains. - [PORTABILITY] Fix build on Alpine Linux. - [PORTABILITY] Fix build using XCode. - Client initial DCID length: use RAND_bytes() instead of rand(3). - Add unit tests for connection min heap. - [DEBUG] Log CID in gQUIC handshake module - [DEBUG] Turn on extra checks for IETF client send controller. - [DEBUG] Dedup next advisory tick messages when reason is IDLE timer. - [DEBUG] QPACK decoder handler: log header error code.
This commit is contained in:
parent
d6937ddce0
commit
a137764bf2
22 changed files with 369 additions and 76 deletions
15
CHANGELOG
15
CHANGELOG
|
@ -1,3 +1,18 @@
|
||||||
|
2019-12-11
|
||||||
|
- 2.7.2
|
||||||
|
- [BUGFIX] Send controller: update scheduled bytes when DCID length
|
||||||
|
changes (IETF client).
|
||||||
|
- [BUGFIX] Drop alarm check from sanity test. It no longer works now
|
||||||
|
that we use loss chains.
|
||||||
|
- [PORTABILITY] Fix build on Alpine Linux.
|
||||||
|
- [PORTABILITY] Fix build using XCode.
|
||||||
|
- Client initial DCID length: use RAND_bytes() instead of rand(3).
|
||||||
|
- Add unit tests for connection min heap.
|
||||||
|
- [DEBUG] Log CID in gQUIC handshake module
|
||||||
|
- [DEBUG] Turn on extra checks for IETF client send controller.
|
||||||
|
- [DEBUG] Dedup next advisory tick messages when reason is IDLE timer.
|
||||||
|
- [DEBUG] QPACK decoder handler: log header error code.
|
||||||
|
|
||||||
2019-12-05
|
2019-12-05
|
||||||
- 2.7.1
|
- 2.7.1
|
||||||
- [BUGFIX] client: don't call ignore_init() in middle of batch send.
|
- [BUGFIX] client: don't call ignore_init() in middle of batch send.
|
||||||
|
|
|
@ -7,6 +7,8 @@ to the LiteSpeed Client Library:
|
||||||
- Alexis La Goutte -- Travis-CI integration
|
- Alexis La Goutte -- Travis-CI integration
|
||||||
- Bernhard Jaeger -- DNS Resolution
|
- Bernhard Jaeger -- DNS Resolution
|
||||||
- Zhang Chi -- libevent build fix on Darwin
|
- Zhang Chi -- libevent build fix on Darwin
|
||||||
|
- Omar Roth -- Alpine Linux build and Crystal language bindings
|
||||||
|
- initlife (?) -- XCode build
|
||||||
|
|
||||||
Thank you!
|
Thank you!
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
||||||
|
|
||||||
#define LSQUIC_MAJOR_VERSION 2
|
#define LSQUIC_MAJOR_VERSION 2
|
||||||
#define LSQUIC_MINOR_VERSION 7
|
#define LSQUIC_MINOR_VERSION 7
|
||||||
#define LSQUIC_PATCH_VERSION 1
|
#define LSQUIC_PATCH_VERSION 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Engine flags:
|
* Engine flags:
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
@ -238,8 +237,12 @@ void
|
||||||
lsquic_generate_cid (lsquic_cid_t *cid, size_t len)
|
lsquic_generate_cid (lsquic_cid_t *cid, size_t len)
|
||||||
{
|
{
|
||||||
if (!len)
|
if (!len)
|
||||||
|
{
|
||||||
/* If not set, generate ID between 8 and MAX_CID_LEN bytes in length */
|
/* If not set, generate ID between 8 and MAX_CID_LEN bytes in length */
|
||||||
len = 8 + rand() % (MAX_CID_LEN - 7);
|
RAND_bytes((uint8_t *) &len, sizeof(len));
|
||||||
|
len %= MAX_CID_LEN - 7;
|
||||||
|
len += 8;
|
||||||
|
}
|
||||||
RAND_bytes(cid->idbuf, len);
|
RAND_bytes(cid->idbuf, len);
|
||||||
cid->len = len;
|
cid->len = len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,9 @@ struct enc_session_funcs_common
|
||||||
int
|
int
|
||||||
(*esf_alg_keysize) (enc_session_t *);
|
(*esf_alg_keysize) (enc_session_t *);
|
||||||
|
|
||||||
|
/* Need to pass lconn in encrypt and decrypt methods because enc_session
|
||||||
|
* is allowed to be NULL for gQUIC.
|
||||||
|
*/
|
||||||
enum enc_packout
|
enum enc_packout
|
||||||
(*esf_encrypt_packet) (enc_session_t *, const struct lsquic_engine_public *,
|
(*esf_encrypt_packet) (enc_session_t *, const struct lsquic_engine_public *,
|
||||||
struct lsquic_conn *, struct lsquic_packet_out *);
|
struct lsquic_conn *, struct lsquic_packet_out *);
|
||||||
|
@ -119,6 +122,9 @@ struct enc_session_funcs_common
|
||||||
int
|
int
|
||||||
(*esf_is_zero_rtt_enabled) (enc_session_t *);
|
(*esf_is_zero_rtt_enabled) (enc_session_t *);
|
||||||
|
|
||||||
|
void
|
||||||
|
(*esf_set_conn) (enc_session_t *, struct lsquic_conn *);
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
esf_tag_len;
|
esf_tag_len;
|
||||||
};
|
};
|
||||||
|
@ -147,7 +153,8 @@ struct enc_session_funcs_gquic
|
||||||
|
|
||||||
/* Create server session */
|
/* Create server session */
|
||||||
enc_session_t *
|
enc_session_t *
|
||||||
(*esf_create_server) (lsquic_cid_t cid, const struct lsquic_engine_public *);
|
(*esf_create_server) (struct lsquic_conn *,
|
||||||
|
lsquic_cid_t cid, const struct lsquic_engine_public *);
|
||||||
|
|
||||||
/* out_len should have init value as the max length of out */
|
/* out_len should have init value as the max length of out */
|
||||||
enum handshake_error
|
enum handshake_error
|
||||||
|
@ -208,7 +215,8 @@ struct enc_session_funcs_gquic
|
||||||
|
|
||||||
/* Create client session */
|
/* Create client session */
|
||||||
enc_session_t *
|
enc_session_t *
|
||||||
(*esf_create_client) (const char *domain, lsquic_cid_t cid,
|
(*esf_create_client) (struct lsquic_conn *, const char *domain,
|
||||||
|
lsquic_cid_t cid,
|
||||||
const struct lsquic_engine_public *,
|
const struct lsquic_engine_public *,
|
||||||
const unsigned char *, size_t);
|
const unsigned char *, size_t);
|
||||||
|
|
||||||
|
@ -229,7 +237,6 @@ struct enc_session_funcs_gquic
|
||||||
* call it after the "handshake is done" callback is called.
|
* call it after the "handshake is done" callback is called.
|
||||||
*/
|
*/
|
||||||
void (*esf_maybe_dispatch_zero_rtt) (enc_session_t *,
|
void (*esf_maybe_dispatch_zero_rtt) (enc_session_t *,
|
||||||
struct lsquic_conn *conn,
|
|
||||||
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t));
|
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t));
|
||||||
|
|
||||||
void (*esf_reset_cid) (enc_session_t *, const lsquic_cid_t *);
|
void (*esf_reset_cid) (enc_session_t *, const lsquic_cid_t *);
|
||||||
|
@ -279,9 +286,6 @@ struct enc_session_funcs_iquic
|
||||||
int
|
int
|
||||||
(*esfi_init_server) (enc_session_t *);
|
(*esfi_init_server) (enc_session_t *);
|
||||||
|
|
||||||
void
|
|
||||||
(*esfi_set_conn) (enc_session_t *, struct lsquic_conn *);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
(*esfi_set_streams) (enc_session_t *, void *(crypto_streams)[4],
|
(*esfi_set_streams) (enc_session_t *, void *(crypto_streams)[4],
|
||||||
const struct crypto_stream_if *);
|
const struct crypto_stream_if *);
|
||||||
|
|
|
@ -1064,7 +1064,7 @@ iquic_lookup_cert (SSL *ssl, void *arg)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iquic_esfi_set_conn (enc_session_t *enc_session_p, struct lsquic_conn *lconn)
|
iquic_esf_set_conn (enc_session_t *enc_session_p, struct lsquic_conn *lconn)
|
||||||
{
|
{
|
||||||
struct enc_sess_iquic *const enc_sess = enc_session_p;
|
struct enc_sess_iquic *const enc_sess = enc_session_p;
|
||||||
enc_sess->esi_conn = lconn;
|
enc_sess->esi_conn = lconn;
|
||||||
|
@ -1657,10 +1657,11 @@ static const enum enc_level pns2enc_level[] =
|
||||||
|
|
||||||
static enum enc_packout
|
static enum enc_packout
|
||||||
iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
||||||
const struct lsquic_engine_public *enpub, struct lsquic_conn *lconn,
|
const struct lsquic_engine_public *enpub, struct lsquic_conn *lconn_UNUSED,
|
||||||
struct lsquic_packet_out *packet_out)
|
struct lsquic_packet_out *packet_out)
|
||||||
{
|
{
|
||||||
struct enc_sess_iquic *const enc_sess = enc_session_p;
|
struct enc_sess_iquic *const enc_sess = enc_session_p;
|
||||||
|
struct lsquic_conn *const lconn = enc_sess->esi_conn;
|
||||||
unsigned char *dst;
|
unsigned char *dst;
|
||||||
const struct crypto_ctx_pair *pair;
|
const struct crypto_ctx_pair *pair;
|
||||||
const struct crypto_ctx *crypto_ctx;
|
const struct crypto_ctx *crypto_ctx;
|
||||||
|
@ -1676,8 +1677,6 @@ iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
||||||
enum packnum_space pns;
|
enum packnum_space pns;
|
||||||
char errbuf[ERR_ERROR_STRING_BUF_LEN];
|
char errbuf[ERR_ERROR_STRING_BUF_LEN];
|
||||||
|
|
||||||
assert(lconn == enc_sess->esi_conn);
|
|
||||||
|
|
||||||
if (packet_out->po_flags & PO_MINI)
|
if (packet_out->po_flags & PO_MINI)
|
||||||
{
|
{
|
||||||
/* XXX TODO Don't rely on PO_MINI, generalize this logic */
|
/* XXX TODO Don't rely on PO_MINI, generalize this logic */
|
||||||
|
@ -2232,7 +2231,6 @@ const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1 =
|
||||||
= iquic_esfi_get_peer_transport_params,
|
= iquic_esfi_get_peer_transport_params,
|
||||||
.esfi_reset_dcid = iquic_esfi_reset_dcid,
|
.esfi_reset_dcid = iquic_esfi_reset_dcid,
|
||||||
.esfi_init_server = iquic_esfi_init_server,
|
.esfi_init_server = iquic_esfi_init_server,
|
||||||
.esfi_set_conn = iquic_esfi_set_conn,
|
|
||||||
.esfi_set_streams = iquic_esfi_set_streams,
|
.esfi_set_streams = iquic_esfi_set_streams,
|
||||||
.esfi_create_server = iquic_esfi_create_server,
|
.esfi_create_server = iquic_esfi_create_server,
|
||||||
.esfi_shake_stream = iquic_esfi_shake_stream,
|
.esfi_shake_stream = iquic_esfi_shake_stream,
|
||||||
|
@ -2253,6 +2251,7 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1 =
|
||||||
.esf_keysize = iquic_esf_keysize,
|
.esf_keysize = iquic_esf_keysize,
|
||||||
.esf_alg_keysize = iquic_esf_alg_keysize,
|
.esf_alg_keysize = iquic_esf_alg_keysize,
|
||||||
.esf_is_zero_rtt_enabled = iquic_esf_zero_rtt_enabled,
|
.esf_is_zero_rtt_enabled = iquic_esf_zero_rtt_enabled,
|
||||||
|
.esf_set_conn = iquic_esf_set_conn,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,10 @@
|
||||||
#define LSQUIC_DEBUG_NEXT_ADV_TICK 1
|
#define LSQUIC_DEBUG_NEXT_ADV_TICK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
||||||
|
#include "lsquic_alarmset.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
/* The batch of outgoing packets grows and shrinks dynamically */
|
/* The batch of outgoing packets grows and shrinks dynamically */
|
||||||
|
@ -248,6 +252,9 @@ struct lsquic_engine
|
||||||
#if LSQUIC_COUNT_ENGINE_CALLS
|
#if LSQUIC_COUNT_ENGINE_CALLS
|
||||||
unsigned long n_engine_calls;
|
unsigned long n_engine_calls;
|
||||||
#endif
|
#endif
|
||||||
|
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
||||||
|
uintptr_t last_logged_idle_conn;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2543,9 +2550,6 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
||||||
(void) engine_decref_conn(engine, conn, LSCONN_CLOSING);
|
(void) engine_decref_conn(engine, conn, LSCONN_CLOSING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO Heapification can be optimized by switching to the Floyd method:
|
|
||||||
* https://en.wikipedia.org/wiki/Binary_heap#Building_a_heap
|
|
||||||
*/
|
|
||||||
while ((conn = TAILQ_FIRST(&ticked_conns)))
|
while ((conn = TAILQ_FIRST(&ticked_conns)))
|
||||||
{
|
{
|
||||||
TAILQ_REMOVE(&ticked_conns, conn, cn_next_ticked);
|
TAILQ_REMOVE(&ticked_conns, conn, cn_next_ticked);
|
||||||
|
@ -2553,6 +2557,7 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
||||||
if (!(conn->cn_flags & LSCONN_TICKABLE)
|
if (!(conn->cn_flags & LSCONN_TICKABLE)
|
||||||
&& conn->cn_if->ci_is_tickable(conn))
|
&& conn->cn_if->ci_is_tickable(conn))
|
||||||
{
|
{
|
||||||
|
/* Floyd heapification is not faster, don't bother. */
|
||||||
lsquic_mh_insert(&engine->conns_tickable, conn, conn->cn_last_ticked);
|
lsquic_mh_insert(&engine->conns_tickable, conn, conn->cn_last_ticked);
|
||||||
engine_incref_conn(conn, LSCONN_TICKABLE);
|
engine_incref_conn(conn, LSCONN_TICKABLE);
|
||||||
}
|
}
|
||||||
|
@ -2709,6 +2714,7 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
|
||||||
{
|
{
|
||||||
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
||||||
conn = lsquic_mh_peek(&engine->conns_out);
|
conn = lsquic_mh_peek(&engine->conns_out);
|
||||||
|
engine->last_logged_idle_conn = 0;
|
||||||
LSQ_LOGC(L, "next advisory tick is now: went past deadline last time "
|
LSQ_LOGC(L, "next advisory tick is now: went past deadline last time "
|
||||||
"and have %u outgoing connection%.*s (%"CID_FMT" first)",
|
"and have %u outgoing connection%.*s (%"CID_FMT" first)",
|
||||||
lsquic_mh_count(&engine->conns_out),
|
lsquic_mh_count(&engine->conns_out),
|
||||||
|
@ -2722,6 +2728,7 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
|
||||||
if (engine->pr_queue && prq_have_pending(engine->pr_queue))
|
if (engine->pr_queue && prq_have_pending(engine->pr_queue))
|
||||||
{
|
{
|
||||||
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
||||||
|
engine->last_logged_idle_conn = 0;
|
||||||
LSQ_LOG(L, "next advisory tick is now: have pending PRQ elements");
|
LSQ_LOG(L, "next advisory tick is now: have pending PRQ elements");
|
||||||
#endif
|
#endif
|
||||||
*diff = 0;
|
*diff = 0;
|
||||||
|
@ -2732,6 +2739,7 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
|
||||||
{
|
{
|
||||||
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
||||||
conn = lsquic_mh_peek(&engine->conns_tickable);
|
conn = lsquic_mh_peek(&engine->conns_tickable);
|
||||||
|
engine->last_logged_idle_conn = 0;
|
||||||
LSQ_LOGC(L, "next advisory tick is now: have %u tickable "
|
LSQ_LOGC(L, "next advisory tick is now: have %u tickable "
|
||||||
"connection%.*s (%"CID_FMT" first)",
|
"connection%.*s (%"CID_FMT" first)",
|
||||||
lsquic_mh_count(&engine->conns_tickable),
|
lsquic_mh_count(&engine->conns_tickable),
|
||||||
|
@ -2769,9 +2777,21 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
|
||||||
*diff = (int) ((int64_t) next_time - (int64_t) now);
|
*diff = (int) ((int64_t) next_time - (int64_t) now);
|
||||||
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
#if LSQUIC_DEBUG_NEXT_ADV_TICK
|
||||||
if (next_attq)
|
if (next_attq)
|
||||||
|
{
|
||||||
|
/* Deduplicate consecutive log messages about IDLE timer for the
|
||||||
|
* same connection.
|
||||||
|
*/
|
||||||
|
if (!((unsigned) next_attq->ae_why == (unsigned) (N_AEWS + AL_IDLE)
|
||||||
|
&& (uintptr_t) next_attq->ae_conn
|
||||||
|
== engine->last_logged_idle_conn))
|
||||||
|
{
|
||||||
|
if ((unsigned) next_attq->ae_why == (unsigned) (N_AEWS + AL_IDLE))
|
||||||
|
engine->last_logged_idle_conn = (uintptr_t) next_attq->ae_conn;
|
||||||
LSQ_LOGC(L, "next advisory tick is %d usec away: conn %"CID_FMT
|
LSQ_LOGC(L, "next advisory tick is %d usec away: conn %"CID_FMT
|
||||||
": %s", *diff, CID_BITS(lsquic_conn_log_cid(next_attq->ae_conn)),
|
": %s", *diff, CID_BITS(lsquic_conn_log_cid(next_attq->ae_conn)),
|
||||||
lsquic_attq_why2str(next_attq->ae_why));
|
lsquic_attq_why2str(next_attq->ae_why));
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
LSQ_LOG(L, "next advisory tick is %d usec away: resume sending", *diff);
|
LSQ_LOG(L, "next advisory tick is %d usec away: resume sending", *diff);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -708,8 +708,8 @@ lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *enpub,
|
||||||
conn->fc_conn.cn_esf_c = select_esf_common_by_ver(version);
|
conn->fc_conn.cn_esf_c = select_esf_common_by_ver(version);
|
||||||
conn->fc_conn.cn_esf.g = esf_g;
|
conn->fc_conn.cn_esf.g = esf_g;
|
||||||
conn->fc_conn.cn_enc_session =
|
conn->fc_conn.cn_enc_session =
|
||||||
conn->fc_conn.cn_esf.g->esf_create_client(hostname, cid, conn->fc_enpub,
|
conn->fc_conn.cn_esf.g->esf_create_client(&conn->fc_conn, hostname,
|
||||||
zero_rtt, zero_rtt_len);
|
cid, conn->fc_enpub, zero_rtt, zero_rtt_len);
|
||||||
if (!conn->fc_conn.cn_enc_session)
|
if (!conn->fc_conn.cn_enc_session)
|
||||||
{
|
{
|
||||||
LSQ_WARN("could not create enc session: %s", strerror(errno));
|
LSQ_WARN("could not create enc session: %s", strerror(errno));
|
||||||
|
@ -818,6 +818,8 @@ lsquic_gquic_full_conn_server_new (struct lsquic_engine_public *enpub,
|
||||||
assert(lconn_full->cn_enc_session == NULL);
|
assert(lconn_full->cn_enc_session == NULL);
|
||||||
lconn_full->cn_enc_session = lconn_mini->cn_enc_session;
|
lconn_full->cn_enc_session = lconn_mini->cn_enc_session;
|
||||||
lconn_mini->cn_enc_session = NULL;
|
lconn_mini->cn_enc_session = NULL;
|
||||||
|
lconn_full->cn_esf_c->esf_set_conn(lconn_full->cn_enc_session,
|
||||||
|
&conn->fc_conn);
|
||||||
|
|
||||||
lsquic_send_ctl_verneg_done(&conn->fc_send_ctl);
|
lsquic_send_ctl_verneg_done(&conn->fc_send_ctl);
|
||||||
conn->fc_send_ctl.sc_cur_packno = mc->mc_cur_packno;
|
conn->fc_send_ctl.sc_cur_packno = mc->mc_cur_packno;
|
||||||
|
@ -3640,7 +3642,7 @@ 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_zero_rtt_info)
|
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(
|
conn->fc_conn.cn_esf.g->esf_maybe_dispatch_zero_rtt(
|
||||||
conn->fc_conn.cn_enc_session, &conn->fc_conn,
|
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_zero_rtt_info);
|
||||||
if (conn->fc_n_delayed_streams)
|
if (conn->fc_n_delayed_streams)
|
||||||
create_delayed_streams(conn);
|
create_delayed_streams(conn);
|
||||||
|
|
|
@ -1209,7 +1209,7 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
|
||||||
|
|
||||||
conn->ifc_conn.cn_enc_session = mini_conn->cn_enc_session;
|
conn->ifc_conn.cn_enc_session = mini_conn->cn_enc_session;
|
||||||
mini_conn->cn_enc_session = NULL;
|
mini_conn->cn_enc_session = NULL;
|
||||||
conn->ifc_conn.cn_esf.i->esfi_set_conn(conn->ifc_conn.cn_enc_session,
|
conn->ifc_conn.cn_esf_c->esf_set_conn(conn->ifc_conn.cn_enc_session,
|
||||||
&conn->ifc_conn);
|
&conn->ifc_conn);
|
||||||
conn->ifc_process_incoming_packet = process_incoming_packet_fast;
|
conn->ifc_process_incoming_packet = process_incoming_packet_fast;
|
||||||
|
|
||||||
|
@ -5672,6 +5672,21 @@ sockaddr_eq (const struct sockaddr *a, const struct sockaddr *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
record_dcid (struct ietf_full_conn *conn,
|
||||||
|
const struct lsquic_packet_in *packet_in)
|
||||||
|
{
|
||||||
|
unsigned orig_cid_len;
|
||||||
|
|
||||||
|
orig_cid_len = CUR_DCID(conn)->len;
|
||||||
|
conn->ifc_flags |= IFC_DCID_SET;
|
||||||
|
lsquic_scid_from_packet_in(packet_in, CUR_DCID(conn));
|
||||||
|
LSQ_DEBUGC("set DCID to %"CID_FMT, CID_BITS(CUR_DCID(conn)));
|
||||||
|
lsquic_send_ctl_cidlen_change(&conn->ifc_send_ctl, orig_cid_len,
|
||||||
|
CUR_DCID(conn)->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_regular_packet (struct ietf_full_conn *conn,
|
process_regular_packet (struct ietf_full_conn *conn,
|
||||||
struct lsquic_packet_in *packet_in)
|
struct lsquic_packet_in *packet_in)
|
||||||
|
@ -5784,12 +5799,7 @@ process_regular_packet (struct ietf_full_conn *conn,
|
||||||
case REC_ST_OK:
|
case REC_ST_OK:
|
||||||
if (!(conn->ifc_flags & (IFC_SERVER|IFC_DCID_SET))
|
if (!(conn->ifc_flags & (IFC_SERVER|IFC_DCID_SET))
|
||||||
&& (packet_in->pi_scid_len))
|
&& (packet_in->pi_scid_len))
|
||||||
{
|
record_dcid(conn, packet_in);
|
||||||
conn->ifc_flags |= IFC_DCID_SET;
|
|
||||||
lsquic_scid_from_packet_in(packet_in, CUR_DCID(conn));
|
|
||||||
LSQ_DEBUGC("set DCID to %"CID_FMT,
|
|
||||||
CID_BITS(CUR_DCID(conn)));
|
|
||||||
}
|
|
||||||
saved_path_id = conn->ifc_cur_path_id;
|
saved_path_id = conn->ifc_cur_path_id;
|
||||||
parse_regular_packet(conn, packet_in);
|
parse_regular_packet(conn, packet_in);
|
||||||
if (saved_path_id == conn->ifc_cur_path_id)
|
if (saved_path_id == conn->ifc_cur_path_id)
|
||||||
|
|
|
@ -56,8 +56,19 @@
|
||||||
#define MAX_SPUBS_LENGTH 32
|
#define MAX_SPUBS_LENGTH 32
|
||||||
|
|
||||||
#define LSQUIC_LOGGER_MODULE LSQLM_HANDSHAKE
|
#define LSQUIC_LOGGER_MODULE LSQLM_HANDSHAKE
|
||||||
|
#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid( \
|
||||||
|
enc_session && enc_session->es_conn ? enc_session->es_conn : \
|
||||||
|
lconn && lconn != &dummy_lsquic_conn ? lconn : \
|
||||||
|
&dummy_lsquic_conn)
|
||||||
#include "lsquic_logger.h"
|
#include "lsquic_logger.h"
|
||||||
|
|
||||||
|
/* enc_session may be NULL when encrypt and decrypt packet functions are
|
||||||
|
* called. This is a workaround.
|
||||||
|
*/
|
||||||
|
static struct conn_cid_elem dummy_cce;
|
||||||
|
static const struct lsquic_conn dummy_lsquic_conn = { .cn_cces = &dummy_cce, };
|
||||||
|
static const struct lsquic_conn *const lconn = &dummy_lsquic_conn;
|
||||||
|
|
||||||
enum handshake_state
|
enum handshake_state
|
||||||
{
|
{
|
||||||
HSK_CHLO_REJ = 0,
|
HSK_CHLO_REJ = 0,
|
||||||
|
@ -200,6 +211,7 @@ struct lsquic_zero_rtt_storage
|
||||||
|
|
||||||
struct lsquic_enc_session
|
struct lsquic_enc_session
|
||||||
{
|
{
|
||||||
|
struct lsquic_conn *es_conn;
|
||||||
enum handshake_state hsk_state;
|
enum handshake_state hsk_state;
|
||||||
enum {
|
enum {
|
||||||
ES_SERVER = 1 << 0,
|
ES_SERVER = 1 << 0,
|
||||||
|
@ -674,8 +686,8 @@ lsquic_enc_session_deserialize_zero_rtt(
|
||||||
|
|
||||||
|
|
||||||
static enc_session_t *
|
static enc_session_t *
|
||||||
lsquic_enc_session_create_client (const char *domain, lsquic_cid_t cid,
|
lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
|
||||||
const struct lsquic_engine_public *enpub,
|
lsquic_cid_t cid, const struct lsquic_engine_public *enpub,
|
||||||
const unsigned char *zero_rtt, size_t zero_rtt_len)
|
const unsigned char *zero_rtt, size_t zero_rtt_len)
|
||||||
{
|
{
|
||||||
lsquic_session_cache_info_t *info;
|
lsquic_session_cache_info_t *info;
|
||||||
|
@ -734,6 +746,7 @@ lsquic_enc_session_create_client (const char *domain, lsquic_cid_t cid,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
enc_session->es_conn = lconn;
|
||||||
enc_session->enpub = enpub;
|
enc_session->enpub = enpub;
|
||||||
enc_session->cid = cid;
|
enc_session->cid = cid;
|
||||||
enc_session->info = info;
|
enc_session->info = info;
|
||||||
|
@ -745,7 +758,7 @@ lsquic_enc_session_create_client (const char *domain, lsquic_cid_t cid,
|
||||||
|
|
||||||
/* Server side: Session_cache_entry can be saved for 0rtt */
|
/* Server side: Session_cache_entry can be saved for 0rtt */
|
||||||
static enc_session_t *
|
static enc_session_t *
|
||||||
lsquic_enc_session_create_server (lsquic_cid_t cid,
|
lsquic_enc_session_create_server (struct lsquic_conn *lconn, lsquic_cid_t cid,
|
||||||
const struct lsquic_engine_public *enpub)
|
const struct lsquic_engine_public *enpub)
|
||||||
{
|
{
|
||||||
fiu_return_on("handshake/new_enc_session", NULL);
|
fiu_return_on("handshake/new_enc_session", NULL);
|
||||||
|
@ -756,6 +769,7 @@ lsquic_enc_session_create_server (lsquic_cid_t cid,
|
||||||
if (!enc_session)
|
if (!enc_session)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
enc_session->es_conn = lconn;
|
||||||
enc_session->enpub = enpub;
|
enc_session->enpub = enpub;
|
||||||
enc_session->cid = cid;
|
enc_session->cid = cid;
|
||||||
enc_session->es_flags |= ES_SERVER;
|
enc_session->es_flags |= ES_SERVER;
|
||||||
|
@ -1575,7 +1589,8 @@ determine_rtts (struct lsquic_enc_session *enc_session,
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
config_has_correct_size (const void *data, unsigned shm_len)
|
config_has_correct_size (const struct lsquic_enc_session *enc_session,
|
||||||
|
const void *data, unsigned shm_len)
|
||||||
{
|
{
|
||||||
/* EVP_AEAD_CTX from boringssl after-18d9f28f0df9f95570. */
|
/* EVP_AEAD_CTX from boringssl after-18d9f28f0df9f95570. */
|
||||||
struct new_evp_aead_ctx_st {
|
struct new_evp_aead_ctx_st {
|
||||||
|
@ -1620,7 +1635,8 @@ config_has_correct_size (const void *data, unsigned shm_len)
|
||||||
|
|
||||||
|
|
||||||
static lsquic_server_config_t *
|
static lsquic_server_config_t *
|
||||||
get_valid_scfg (const struct lsquic_engine_public *enpub)
|
get_valid_scfg (const struct lsquic_enc_session *enc_session,
|
||||||
|
const struct lsquic_engine_public *enpub)
|
||||||
{
|
{
|
||||||
#define SERVER_SCFG_KEY "SERVER_SCFG"
|
#define SERVER_SCFG_KEY "SERVER_SCFG"
|
||||||
#define SERVER_SCFG_KEY_SIZE (sizeof(SERVER_SCFG_KEY) - 1)
|
#define SERVER_SCFG_KEY_SIZE (sizeof(SERVER_SCFG_KEY) - 1)
|
||||||
|
@ -1644,7 +1660,7 @@ get_valid_scfg (const struct lsquic_engine_public *enpub)
|
||||||
&scfg_ptr, &real_len);
|
&scfg_ptr, &real_len);
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
{
|
{
|
||||||
if (config_has_correct_size(scfg_ptr, real_len) &&
|
if (config_has_correct_size(enc_session, scfg_ptr, real_len) &&
|
||||||
(s_server_config.lsc_scfg = scfg_ptr,
|
(s_server_config.lsc_scfg = scfg_ptr,
|
||||||
s_server_config.lsc_scfg->info.expy > (uint64_t)t))
|
s_server_config.lsc_scfg->info.expy > (uint64_t)t))
|
||||||
{
|
{
|
||||||
|
@ -2621,7 +2637,8 @@ gen_stk (lsquic_server_config_t *server_config, const struct sockaddr *ip_addr,
|
||||||
static
|
static
|
||||||
#endif
|
#endif
|
||||||
enum hsk_failure_reason
|
enum hsk_failure_reason
|
||||||
verify_stk0 (lsquic_server_config_t *server_config,
|
verify_stk0 (const struct lsquic_enc_session *enc_session,
|
||||||
|
lsquic_server_config_t *server_config,
|
||||||
const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk,
|
const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk,
|
||||||
unsigned secs_since_stk_generated)
|
unsigned secs_since_stk_generated)
|
||||||
{
|
{
|
||||||
|
@ -2701,7 +2718,8 @@ verify_stk (enc_session_t *enc_session_p,
|
||||||
return HFR_SRC_ADDR_TOKEN_INVALID;
|
return HFR_SRC_ADDR_TOKEN_INVALID;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return verify_stk0(enc_session->server_config, ip_addr, tm, stk, 0);
|
return verify_stk0(enc_session, enc_session->server_config, ip_addr,
|
||||||
|
tm, stk, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2850,14 +2868,13 @@ lsquic_enc_session_have_key_gt_one (enc_session_t *enc_session_p)
|
||||||
* buffer correspond to the header and the payload of incoming QUIC packet.
|
* buffer correspond to the header and the payload of incoming QUIC packet.
|
||||||
*/
|
*/
|
||||||
static enum enc_level
|
static enum enc_level
|
||||||
lsquic_enc_session_decrypt (enc_session_t *enc_session_p,
|
lsquic_enc_session_decrypt (struct lsquic_enc_session *enc_session,
|
||||||
enum lsquic_version version,
|
enum lsquic_version version,
|
||||||
uint8_t path_id, uint64_t pack_num,
|
uint8_t path_id, uint64_t pack_num,
|
||||||
unsigned char *buf, size_t *header_len, size_t data_len,
|
unsigned char *buf, size_t *header_len, size_t data_len,
|
||||||
unsigned char *diversification_nonce,
|
unsigned char *diversification_nonce,
|
||||||
unsigned char *buf_out, size_t max_out_len, size_t *out_len)
|
unsigned char *buf_out, size_t max_out_len, size_t *out_len)
|
||||||
{
|
{
|
||||||
struct lsquic_enc_session *const enc_session = enc_session_p;
|
|
||||||
/* Client: got SHLO which should have diversification_nonce */
|
/* Client: got SHLO which should have diversification_nonce */
|
||||||
if (diversification_nonce && enc_session && enc_session->have_key == 1)
|
if (diversification_nonce && enc_session && enc_session->have_key == 1)
|
||||||
{
|
{
|
||||||
|
@ -2882,6 +2899,7 @@ gquic_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
const struct lsquic_conn *lconn,
|
const struct lsquic_conn *lconn,
|
||||||
struct lsquic_packet_in *packet_in)
|
struct lsquic_packet_in *packet_in)
|
||||||
{
|
{
|
||||||
|
struct lsquic_enc_session *const enc_session = enc_session_p;
|
||||||
size_t header_len, data_len;
|
size_t header_len, data_len;
|
||||||
enum enc_level enc_level;
|
enum enc_level enc_level;
|
||||||
size_t out_len = 0;
|
size_t out_len = 0;
|
||||||
|
@ -2895,7 +2913,7 @@ gquic_decrypt_packet (enc_session_t *enc_session_p,
|
||||||
assert(packet_in->pi_data);
|
assert(packet_in->pi_data);
|
||||||
header_len = packet_in->pi_header_sz;
|
header_len = packet_in->pi_header_sz;
|
||||||
data_len = packet_in->pi_data_sz - packet_in->pi_header_sz;
|
data_len = packet_in->pi_data_sz - packet_in->pi_header_sz;
|
||||||
enc_level = lsquic_enc_session_decrypt(enc_session_p,
|
enc_level = lsquic_enc_session_decrypt(enc_session,
|
||||||
lconn->cn_version, 0,
|
lconn->cn_version, 0,
|
||||||
packet_in->pi_packno, packet_in->pi_data,
|
packet_in->pi_packno, packet_in->pi_data,
|
||||||
&header_len, data_len,
|
&header_len, data_len,
|
||||||
|
@ -3030,7 +3048,7 @@ lsquic_enc_session_handle_chlo(enc_session_t *enc_session_p,
|
||||||
const struct lsquic_shared_hash_if *const shi = enpub->enp_shi;
|
const struct lsquic_shared_hash_if *const shi = enpub->enp_shi;
|
||||||
void *const shi_ctx = enpub->enp_shi_ctx;
|
void *const shi_ctx = enpub->enp_shi_ctx;
|
||||||
|
|
||||||
server_config = get_valid_scfg(enpub);
|
server_config = get_valid_scfg(enc_session, enpub);
|
||||||
if (!server_config)
|
if (!server_config)
|
||||||
return HS_ERROR;
|
return HS_ERROR;
|
||||||
assert(server_config->lsc_scfg);
|
assert(server_config->lsc_scfg);
|
||||||
|
@ -3493,10 +3511,10 @@ lsquic_enc_session_get_server_cert_chain (enc_session_t *enc_session_p)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maybe_dispatch_zero_rtt (enc_session_t *enc_session_p,
|
maybe_dispatch_zero_rtt (enc_session_t *enc_session_p,
|
||||||
struct lsquic_conn *lconn,
|
|
||||||
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t))
|
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t))
|
||||||
{
|
{
|
||||||
struct lsquic_enc_session *const enc_session = enc_session_p;
|
struct lsquic_enc_session *const enc_session = enc_session_p;
|
||||||
|
struct lsquic_conn *const lconn = enc_session->es_conn;
|
||||||
void *buf;
|
void *buf;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
int i;
|
int i;
|
||||||
|
@ -3570,6 +3588,8 @@ gquic_encrypt_packet (enc_session_t *enc_session_p,
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
int ipv6;
|
int ipv6;
|
||||||
|
|
||||||
|
assert(!enc_session || lconn == enc_session->es_conn);
|
||||||
|
|
||||||
bufsz = lconn->cn_pf->pf_packout_size(lconn, packet_out);
|
bufsz = lconn->cn_pf->pf_packout_size(lconn, packet_out);
|
||||||
if (bufsz > USHRT_MAX)
|
if (bufsz > USHRT_MAX)
|
||||||
return ENCPA_BADCRYPT; /* To cause connection to close */
|
return ENCPA_BADCRYPT; /* To cause connection to close */
|
||||||
|
@ -3614,6 +3634,15 @@ gquic_encrypt_packet (enc_session_t *enc_session_p,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gquic_esf_set_conn (enc_session_t *enc_session_p, struct lsquic_conn *lconn)
|
||||||
|
{
|
||||||
|
struct lsquic_enc_session *const enc_session = enc_session_p;
|
||||||
|
enc_session->es_conn = lconn;
|
||||||
|
LSQ_DEBUG("updated conn reference");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
const
|
const
|
||||||
#endif
|
#endif
|
||||||
|
@ -3631,6 +3660,7 @@ struct enc_session_funcs_common lsquic_enc_session_common_gquic_1 =
|
||||||
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
|
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
|
||||||
.esf_did_zero_rtt_succeed = lsquic_enc_session_did_zero_rtt_succeed,
|
.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_is_zero_rtt_enabled = lsquic_enc_session_is_zero_rtt_enabled,
|
||||||
|
.esf_set_conn = gquic_esf_set_conn,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct sockaddr;
|
||||||
struct lsquic_str;
|
struct lsquic_str;
|
||||||
struct lsquic_packet_in;
|
struct lsquic_packet_in;
|
||||||
struct lsquic_cid;
|
struct lsquic_cid;
|
||||||
|
struct lsquic_enc_session;
|
||||||
|
|
||||||
/* client side, certs and hashs
|
/* client side, certs and hashs
|
||||||
*/
|
*/
|
||||||
|
@ -28,7 +29,8 @@ typedef struct cert_hash_item_st
|
||||||
void gen_stk(struct lsquic_server_config *, const struct sockaddr *ip_addr, uint64_t tm,
|
void gen_stk(struct lsquic_server_config *, const struct sockaddr *ip_addr, uint64_t tm,
|
||||||
unsigned char stk_out[STK_LENGTH]);
|
unsigned char stk_out[STK_LENGTH]);
|
||||||
enum hsk_failure_reason
|
enum hsk_failure_reason
|
||||||
verify_stk0(struct lsquic_server_config *, const struct sockaddr *ip_addr, uint64_t tm,
|
verify_stk0(const struct lsquic_enc_session *,
|
||||||
|
struct lsquic_server_config *, const struct sockaddr *ip_addr, uint64_t tm,
|
||||||
struct lsquic_str *stk,
|
struct lsquic_str *stk,
|
||||||
unsigned secs_since_stk_generated);
|
unsigned secs_since_stk_generated);
|
||||||
enum hsk_failure_reason
|
enum hsk_failure_reason
|
||||||
|
|
|
@ -82,7 +82,6 @@ enum lsq_log_level lsq_log_levels[N_LSQUIC_LOGGER_MODULES] = {
|
||||||
[LSQLM_DI] = LSQ_LOG_WARN,
|
[LSQLM_DI] = LSQ_LOG_WARN,
|
||||||
[LSQLM_PRQ] = LSQ_LOG_WARN,
|
[LSQLM_PRQ] = LSQ_LOG_WARN,
|
||||||
[LSQLM_PACER] = LSQ_LOG_WARN,
|
[LSQLM_PACER] = LSQ_LOG_WARN,
|
||||||
[LSQLM_MIN_HEAP] = LSQ_LOG_WARN,
|
|
||||||
[LSQLM_HTTP1X] = LSQ_LOG_WARN,
|
[LSQLM_HTTP1X] = LSQ_LOG_WARN,
|
||||||
[LSQLM_QLOG] = LSQ_LOG_WARN,
|
[LSQLM_QLOG] = LSQ_LOG_WARN,
|
||||||
[LSQLM_TRAPA] = LSQ_LOG_WARN,
|
[LSQLM_TRAPA] = LSQ_LOG_WARN,
|
||||||
|
@ -125,7 +124,6 @@ const char *const lsqlm_to_str[N_LSQUIC_LOGGER_MODULES] = {
|
||||||
[LSQLM_DI] = "di",
|
[LSQLM_DI] = "di",
|
||||||
[LSQLM_PRQ] = "prq",
|
[LSQLM_PRQ] = "prq",
|
||||||
[LSQLM_PACER] = "pacer",
|
[LSQLM_PACER] = "pacer",
|
||||||
[LSQLM_MIN_HEAP] = "min-heap",
|
|
||||||
[LSQLM_HTTP1X] = "http1x",
|
[LSQLM_HTTP1X] = "http1x",
|
||||||
[LSQLM_QLOG] = "qlog",
|
[LSQLM_QLOG] = "qlog",
|
||||||
[LSQLM_TRAPA] = "trapa",
|
[LSQLM_TRAPA] = "trapa",
|
||||||
|
|
|
@ -73,7 +73,6 @@ enum lsquic_logger_module {
|
||||||
LSQLM_DI,
|
LSQLM_DI,
|
||||||
LSQLM_PRQ,
|
LSQLM_PRQ,
|
||||||
LSQLM_PACER,
|
LSQLM_PACER,
|
||||||
LSQLM_MIN_HEAP,
|
|
||||||
LSQLM_HTTP1X,
|
LSQLM_HTTP1X,
|
||||||
LSQLM_QLOG,
|
LSQLM_QLOG,
|
||||||
LSQLM_TRAPA,
|
LSQLM_TRAPA,
|
||||||
|
|
|
@ -4,16 +4,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "lsquic_min_heap.h"
|
#include "lsquic_min_heap.h"
|
||||||
#define LSQUIC_LOGGER_MODULE LSQLM_MIN_HEAP
|
|
||||||
#include "lsquic_types.h"
|
|
||||||
#include "lsquic_logger.h"
|
|
||||||
|
|
||||||
#define MHE_PARENT(i) ((i - 1) / 2)
|
|
||||||
#define MHE_LCHILD(i) (2 * i + 1)
|
|
||||||
#define MHE_RCHILD(i) (2 * i + 2)
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -35,4 +35,8 @@ lsquic_mh_pop (struct min_heap *);
|
||||||
|
|
||||||
#define lsquic_mh_nalloc(heap) (+(heap)->mh_nalloc)
|
#define lsquic_mh_nalloc(heap) (+(heap)->mh_nalloc)
|
||||||
|
|
||||||
|
#define MHE_PARENT(i) ((i - 1) / 2)
|
||||||
|
#define MHE_LCHILD(i) (2 * i + 1)
|
||||||
|
#define MHE_RCHILD(i) (2 * i + 2)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1005,8 +1005,8 @@ continue_handshake (struct mini_conn *mc)
|
||||||
if (!mc->mc_conn.cn_enc_session)
|
if (!mc->mc_conn.cn_enc_session)
|
||||||
{
|
{
|
||||||
mc->mc_conn.cn_enc_session =
|
mc->mc_conn.cn_enc_session =
|
||||||
mc->mc_conn.cn_esf.g->esf_create_server(mc->mc_conn.cn_cid,
|
mc->mc_conn.cn_esf.g->esf_create_server(&mc->mc_conn,
|
||||||
mc->mc_enpub);
|
mc->mc_conn.cn_cid, mc->mc_enpub);
|
||||||
if (!mc->mc_conn.cn_enc_session)
|
if (!mc->mc_conn.cn_enc_session)
|
||||||
{
|
{
|
||||||
LSQ_WARN("cannot create new enc session");
|
LSQ_WARN("cannot create new enc session");
|
||||||
|
|
|
@ -1154,7 +1154,7 @@ ietf_mini_conn_ci_packet_in (struct lsquic_conn *lconn,
|
||||||
}
|
}
|
||||||
|
|
||||||
dec_packin = lconn->cn_esf_c->esf_decrypt_packet(lconn->cn_enc_session,
|
dec_packin = lconn->cn_esf_c->esf_decrypt_packet(lconn->cn_enc_session,
|
||||||
conn->imc_enpub, lconn, packet_in);
|
conn->imc_enpub, &conn->imc_conn, packet_in);
|
||||||
if (dec_packin != DECPI_OK)
|
if (dec_packin != DECPI_OK)
|
||||||
{
|
{
|
||||||
/* TODO: handle reordering perhaps? */
|
/* TODO: handle reordering perhaps? */
|
||||||
|
|
|
@ -408,8 +408,11 @@ qdh_supply_hset_to_stream (struct qpack_dec_hdl *qdh,
|
||||||
header->qh_name, header->qh_name_len,
|
header->qh_name, header->qh_name_len,
|
||||||
header->qh_value, header->qh_value_len);
|
header->qh_value, header->qh_value_len);
|
||||||
if (st != LSQUIC_HDR_OK)
|
if (st != LSQUIC_HDR_OK)
|
||||||
|
{
|
||||||
|
LSQ_INFO("header process returned non-OK code %u", (unsigned) st);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lsqpack_dec_destroy_header_list(qlist);
|
lsqpack_dec_destroy_header_list(qlist);
|
||||||
qlist = NULL;
|
qlist = NULL;
|
||||||
|
|
|
@ -347,6 +347,13 @@ lsquic_send_ctl_init (lsquic_send_ctl_t *ctl, struct lsquic_alarmset *alset,
|
||||||
TAILQ_INIT(&ctl->sc_buffered_packets[i].bpq_packets);
|
TAILQ_INIT(&ctl->sc_buffered_packets[i].bpq_packets);
|
||||||
ctl->sc_max_packno_bits = PACKNO_BITS_2; /* Safe value before verneg */
|
ctl->sc_max_packno_bits = PACKNO_BITS_2; /* Safe value before verneg */
|
||||||
ctl->sc_cached_bpt.stream_id = UINT64_MAX;
|
ctl->sc_cached_bpt.stream_id = UINT64_MAX;
|
||||||
|
#if LSQUIC_EXTRA_CHECKS
|
||||||
|
ctl->sc_flags |= SC_SANITY_CHECK;
|
||||||
|
#else
|
||||||
|
if ((ctl->sc_conn_pub->lconn->cn_flags & (LSCONN_IETF|LSCONN_SERVER))
|
||||||
|
== LSCONN_IETF)
|
||||||
|
ctl->sc_flags |= SC_SANITY_CHECK;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1404,9 +1411,8 @@ lsquic_send_ctl_expire_all (lsquic_send_ctl_t *ctl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if LSQUIC_EXTRA_CHECKS
|
|
||||||
void
|
void
|
||||||
lsquic_send_ctl_sanity_check (const lsquic_send_ctl_t *ctl)
|
lsquic_send_ctl_do_sanity_check (const struct lsquic_send_ctl *ctl)
|
||||||
{
|
{
|
||||||
const struct lsquic_packet_out *packet_out;
|
const struct lsquic_packet_out *packet_out;
|
||||||
lsquic_packno_t prev_packno;
|
lsquic_packno_t prev_packno;
|
||||||
|
@ -1414,15 +1420,6 @@ lsquic_send_ctl_sanity_check (const lsquic_send_ctl_t *ctl)
|
||||||
unsigned count, bytes;
|
unsigned count, bytes;
|
||||||
enum packnum_space pns;
|
enum packnum_space pns;
|
||||||
|
|
||||||
assert(!send_ctl_first_unacked_retx_packet(ctl, PNS_APP) ||
|
|
||||||
lsquic_alarmset_is_set(ctl->sc_alset, AL_RETX_APP));
|
|
||||||
if (lsquic_alarmset_is_set(ctl->sc_alset, AL_RETX_APP))
|
|
||||||
{
|
|
||||||
assert(send_ctl_first_unacked_retx_packet(ctl, PNS_APP));
|
|
||||||
assert(lsquic_time_now()
|
|
||||||
< ctl->sc_alset->as_expiry[AL_RETX_APP] + MAX_RTO_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 0, bytes = 0;
|
count = 0, bytes = 0;
|
||||||
for (pns = PNS_INIT; pns <= PNS_APP; ++pns)
|
for (pns = PNS_INIT; pns <= PNS_APP; ++pns)
|
||||||
{
|
{
|
||||||
|
@ -1456,7 +1453,6 @@ lsquic_send_ctl_sanity_check (const lsquic_send_ctl_t *ctl)
|
||||||
assert(count == ctl->sc_n_scheduled);
|
assert(count == ctl->sc_n_scheduled);
|
||||||
assert(bytes == ctl->sc_bytes_scheduled);
|
assert(bytes == ctl->sc_bytes_scheduled);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2814,3 +2810,42 @@ lsquic_send_ctl_return_enc_data (struct lsquic_send_ctl *ctl)
|
||||||
if (packet_out->po_flags & PO_ENCRYPTED)
|
if (packet_out->po_flags & PO_ENCRYPTED)
|
||||||
send_ctl_return_enc_data(ctl, packet_out);
|
send_ctl_return_enc_data(ctl, packet_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* When client updated DCID based on the first packet returned by the server,
|
||||||
|
* we must update the number of bytes scheduled if the DCID length changed
|
||||||
|
* because this length is used to calculate packet size.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
lsquic_send_ctl_cidlen_change (struct lsquic_send_ctl *ctl,
|
||||||
|
unsigned orig_cid_len, unsigned new_cid_len)
|
||||||
|
{
|
||||||
|
unsigned diff;
|
||||||
|
|
||||||
|
assert(!(ctl->sc_conn_pub->lconn->cn_flags & LSCONN_SERVER));
|
||||||
|
if (ctl->sc_n_scheduled)
|
||||||
|
{
|
||||||
|
ctl->sc_flags |= SC_CIDLEN;
|
||||||
|
ctl->sc_cidlen = (signed char) new_cid_len - (signed char) orig_cid_len;
|
||||||
|
if (new_cid_len > orig_cid_len)
|
||||||
|
{
|
||||||
|
diff = new_cid_len - orig_cid_len;
|
||||||
|
diff *= ctl->sc_n_scheduled;
|
||||||
|
ctl->sc_bytes_scheduled += diff;
|
||||||
|
LSQ_DEBUG("increased bytes scheduled by %u bytes to %u",
|
||||||
|
diff, ctl->sc_bytes_scheduled);
|
||||||
|
}
|
||||||
|
else if (new_cid_len < orig_cid_len)
|
||||||
|
{
|
||||||
|
diff = orig_cid_len - new_cid_len;
|
||||||
|
diff *= ctl->sc_n_scheduled;
|
||||||
|
ctl->sc_bytes_scheduled -= diff;
|
||||||
|
LSQ_DEBUG("decreased bytes scheduled by %u bytes to %u",
|
||||||
|
diff, ctl->sc_bytes_scheduled);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LSQ_DEBUG("DCID length did not change");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LSQ_DEBUG("no scheduled packets at the time of DCID change");
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,8 @@ enum send_ctl_flags {
|
||||||
SC_APP_LIMITED = 1 << 12,
|
SC_APP_LIMITED = 1 << 12,
|
||||||
SC_ECN = 1 << 13,
|
SC_ECN = 1 << 13,
|
||||||
SC_QL_BITS = 1 << 14,
|
SC_QL_BITS = 1 << 14,
|
||||||
|
SC_SANITY_CHECK = 1 << 15,
|
||||||
|
SC_CIDLEN = 1 << 16, /* sc_cidlen is set */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct lsquic_send_ctl {
|
typedef struct lsquic_send_ctl {
|
||||||
|
@ -127,6 +129,7 @@ typedef struct lsquic_send_ctl {
|
||||||
lsquic_packno_t sc_cur_rt_end;
|
lsquic_packno_t sc_cur_rt_end;
|
||||||
unsigned sc_loss_count; /* Used to set loss bit */
|
unsigned sc_loss_count; /* Used to set loss bit */
|
||||||
unsigned sc_square_count;/* Used to set square bit */
|
unsigned sc_square_count;/* Used to set square bit */
|
||||||
|
signed char sc_cidlen; /* For debug purposes */
|
||||||
} lsquic_send_ctl_t;
|
} lsquic_send_ctl_t;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -172,12 +175,13 @@ lsquic_send_ctl_expire_all (lsquic_send_ctl_t *ctl);
|
||||||
#define lsquic_send_ctl_largest_ack2ed(ctl, pns) \
|
#define lsquic_send_ctl_largest_ack2ed(ctl, pns) \
|
||||||
(+(ctl)->sc_largest_ack2ed[pns])
|
(+(ctl)->sc_largest_ack2ed[pns])
|
||||||
|
|
||||||
#if LSQUIC_EXTRA_CHECKS
|
|
||||||
void
|
void
|
||||||
lsquic_send_ctl_sanity_check (const lsquic_send_ctl_t *ctl);
|
lsquic_send_ctl_do_sanity_check (const struct lsquic_send_ctl *ctl);
|
||||||
#else
|
|
||||||
# define lsquic_send_ctl_sanity_check(ctl)
|
#define lsquic_send_ctl_sanity_check(ctl) do { \
|
||||||
#endif
|
if ((ctl)->sc_flags & SC_SANITY_CHECK) \
|
||||||
|
lsquic_send_ctl_do_sanity_check(ctl); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
int
|
int
|
||||||
lsquic_send_ctl_have_outgoing_stream_frames (const lsquic_send_ctl_t *);
|
lsquic_send_ctl_have_outgoing_stream_frames (const lsquic_send_ctl_t *);
|
||||||
|
@ -364,4 +368,8 @@ lsquic_send_ctl_maybe_app_limited (struct lsquic_send_ctl *,
|
||||||
(ctl)->sc_flags |= SC_QL_BITS; \
|
(ctl)->sc_flags |= SC_QL_BITS; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
void
|
||||||
|
lsquic_send_ctl_cidlen_change (struct lsquic_send_ctl *,
|
||||||
|
unsigned orig_cid_len, unsigned new_cid_len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -99,6 +99,9 @@ TARGET_LINK_LIBRARIES(graph_cubic ${LIBS})
|
||||||
ADD_EXECUTABLE(mini_parse mini_parse.c ${ADDL_SOURCES})
|
ADD_EXECUTABLE(mini_parse mini_parse.c ${ADDL_SOURCES})
|
||||||
TARGET_LINK_LIBRARIES(mini_parse ${LIBS})
|
TARGET_LINK_LIBRARIES(mini_parse ${LIBS})
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(test_min_heap test_min_heap.c ../../src/liblsquic/lsquic_min_heap.c)
|
||||||
|
ADD_TEST(min_heap test_min_heap)
|
||||||
|
|
||||||
ADD_EXECUTABLE(test_malo_pooled test_malo.c ../../src/liblsquic/lsquic_malo.c)
|
ADD_EXECUTABLE(test_malo_pooled test_malo.c ../../src/liblsquic/lsquic_malo.c)
|
||||||
SET_TARGET_PROPERTIES(test_malo_pooled
|
SET_TARGET_PROPERTIES(test_malo_pooled
|
||||||
PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLSQUIC_USE_POOLS=1")
|
PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLSQUIC_USE_POOLS=1")
|
||||||
|
|
162
test/unittests/test_min_heap.c
Normal file
162
test/unittests/test_min_heap.c
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */
|
||||||
|
/* Test min heap or benchmark heap creation */
|
||||||
|
|
||||||
|
/* Floyd mechanism has been removed. It's not faster. */
|
||||||
|
#define FLOYD 0
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lsquic_min_heap.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
verify_min_heap (const struct min_heap *heap)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < heap->mh_nelem; ++i)
|
||||||
|
{
|
||||||
|
if (MHE_LCHILD(i) < heap->mh_nelem)
|
||||||
|
assert(heap->mh_elems[i].mhe_val <=
|
||||||
|
heap->mh_elems[MHE_LCHILD(i)].mhe_val);
|
||||||
|
if (MHE_RCHILD(i) < heap->mh_nelem)
|
||||||
|
assert(heap->mh_elems[i].mhe_val <=
|
||||||
|
heap->mh_elems[MHE_RCHILD(i)].mhe_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_ELEMS 1000
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_min_heap (void)
|
||||||
|
{
|
||||||
|
struct min_heap heap;
|
||||||
|
uint64_t i, prev_val;
|
||||||
|
void *p;
|
||||||
|
struct min_heap_elem els[MAX_ELEMS];
|
||||||
|
|
||||||
|
heap.mh_elems = els;
|
||||||
|
heap.mh_nalloc = MAX_ELEMS;
|
||||||
|
|
||||||
|
heap.mh_nelem = 0;
|
||||||
|
for (i = 0; i < MAX_ELEMS; ++i)
|
||||||
|
lsquic_mh_insert(&heap, (void *) i, i);
|
||||||
|
verify_min_heap(&heap);
|
||||||
|
for (i = 0; i < MAX_ELEMS; ++i)
|
||||||
|
{
|
||||||
|
p = lsquic_mh_pop(&heap);
|
||||||
|
if (i)
|
||||||
|
assert((uintptr_t) p >= prev_val);
|
||||||
|
prev_val = (uintptr_t) p;
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.mh_nelem = 0;
|
||||||
|
for (i = MAX_ELEMS; i > 0; --i)
|
||||||
|
lsquic_mh_insert(&heap, (void *) i, i);
|
||||||
|
verify_min_heap(&heap);
|
||||||
|
for (i = 0; i < MAX_ELEMS; ++i)
|
||||||
|
{
|
||||||
|
p = lsquic_mh_pop(&heap);
|
||||||
|
if (i)
|
||||||
|
assert((uintptr_t) p >= prev_val);
|
||||||
|
prev_val = (uintptr_t) p;
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.mh_nelem = 0;
|
||||||
|
|
||||||
|
#if FLOYD
|
||||||
|
/* Now use Floyd method */
|
||||||
|
heap.mh_nelem = 0;
|
||||||
|
for (i = 0; i < MAX_ELEMS; ++i)
|
||||||
|
lsquic_mh_push(&heap, NULL, i);
|
||||||
|
lsquic_mh_heapify(&heap);
|
||||||
|
verify_min_heap(&heap);
|
||||||
|
|
||||||
|
heap.mh_nelem = 0;
|
||||||
|
for (i = MAX_ELEMS; i > 0; --i)
|
||||||
|
lsquic_mh_push(&heap, NULL, i);
|
||||||
|
lsquic_mh_heapify(&heap);
|
||||||
|
verify_min_heap(&heap);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
test_min_heap();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc != 4)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: %s nelems iters method\n"
|
||||||
|
" method is 0: insert; 1: floyd\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned i, j, n_iters, nelems;
|
||||||
|
struct min_heap_elem *els;
|
||||||
|
unsigned *vals;
|
||||||
|
struct min_heap heap;
|
||||||
|
|
||||||
|
nelems = atoi(argv[1]);
|
||||||
|
n_iters = atoi(argv[2]);
|
||||||
|
#if FLOYD
|
||||||
|
const int floyd = atoi(argv[3]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vals = malloc(sizeof(vals[0]) * nelems);
|
||||||
|
assert(vals);
|
||||||
|
for (i = 0; i < nelems; ++i)
|
||||||
|
vals[i] = rand();
|
||||||
|
els = malloc(sizeof(els[0]) * nelems);
|
||||||
|
assert(els);
|
||||||
|
heap.mh_elems = els;
|
||||||
|
heap.mh_nalloc = nelems;
|
||||||
|
heap.mh_nelem = 0;
|
||||||
|
#if FLOYD
|
||||||
|
if (floyd)
|
||||||
|
{
|
||||||
|
for (i = 0; i < nelems; ++i)
|
||||||
|
lsquic_mh_push(&heap, NULL, vals[i]);
|
||||||
|
lsquic_mh_heapify(&heap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < nelems; ++i)
|
||||||
|
lsquic_mh_insert(&heap, NULL, vals[i]);
|
||||||
|
verify_min_heap(&heap);
|
||||||
|
|
||||||
|
#if FLOYD
|
||||||
|
if (floyd)
|
||||||
|
{
|
||||||
|
for (j = 0; j < n_iters; ++j)
|
||||||
|
{
|
||||||
|
heap.mh_nelem = 0;
|
||||||
|
for (i = 0; i < nelems; ++i)
|
||||||
|
lsquic_mh_push(&heap, NULL, vals[i]);
|
||||||
|
lsquic_mh_heapify(&heap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
for (j = 0; j < n_iters; ++j)
|
||||||
|
{
|
||||||
|
heap.mh_nelem = 0;
|
||||||
|
for (i = 0; i < nelems; ++i)
|
||||||
|
lsquic_mh_insert(&heap, NULL, vals[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(els);
|
||||||
|
free(vals);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue