mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.11.0
- [FEATURE] QUIC and HTTP/3 Internet Draft 27 support. - [FEATURE] Add experimental delayed ACKs extension. - Drop support for Internet Draft 24. - Code cleanup.
This commit is contained in:
parent
feca77f50d
commit
bc520ef752
38 changed files with 626 additions and 7729 deletions
|
@ -1,3 +1,10 @@
|
|||
2020-02-24
|
||||
- 2.11.0
|
||||
- [FEATURE] QUIC and HTTP/3 Internet Draft 27 support.
|
||||
- [FEATURE] Add experimental delayed ACKs extension.
|
||||
- Drop support for Internet Draft 24.
|
||||
- Code cleanup.
|
||||
|
||||
2020-02-14
|
||||
- 2.10.6
|
||||
- [BUGFIX] HTTP/3 framing: don't misinterpret rare occurence as error.
|
||||
|
|
|
@ -15,7 +15,7 @@ and OpenLiteSpeed. We think it is free of major problems. Nevertheless, do
|
|||
not hesitate to report bugs back to us. Even better, send us fixes and
|
||||
improvements!
|
||||
|
||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-24, and ID-25.
|
||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-25, and ID-27.
|
||||
Support for newer versions will be added soon after they are released.
|
||||
|
||||
Documentation
|
||||
|
|
|
@ -46,13 +46,13 @@ developed by the IETF. Both types are included in a single enum:
|
|||
|
||||
Google QUIC version Q050
|
||||
|
||||
.. member:: LSQVER_ID24
|
||||
|
||||
IETF QUIC version ID (Internet-Draft) 24
|
||||
|
||||
.. member:: LSQVER_ID25
|
||||
|
||||
IETF QUIC version ID 25
|
||||
IETF QUIC version ID (Internet-Draft) 25
|
||||
|
||||
.. member:: LSQVER_ID27
|
||||
|
||||
IETF QUIC version ID 27
|
||||
|
||||
.. member:: N_LSQVER
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ copyright = u'2020, LiteSpeed Technologies'
|
|||
author = u'LiteSpeed Technologies'
|
||||
|
||||
# The short X.Y version
|
||||
version = u'2.10'
|
||||
version = u'2.11'
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = u'2.10.6'
|
||||
release = u'2.11.0'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
|
|
@ -19,7 +19,7 @@ Most of the code in this distribution has been used in our own products
|
|||
-- `LiteSpeed Web Server`_, `LiteSpeed Web ADC`_, and OpenLiteSpeed_ --
|
||||
since 2017.
|
||||
|
||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-24, and ID-25.
|
||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-25, and ID-27.
|
||||
Support for newer versions will be added soon after they are released.
|
||||
|
||||
LSQUIC is licensed under the `MIT License`_; see LICENSE in the source
|
||||
|
|
|
@ -24,8 +24,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define LSQUIC_MAJOR_VERSION 2
|
||||
#define LSQUIC_MINOR_VERSION 10
|
||||
#define LSQUIC_PATCH_VERSION 6
|
||||
#define LSQUIC_MINOR_VERSION 11
|
||||
#define LSQUIC_PATCH_VERSION 0
|
||||
|
||||
/**
|
||||
* Engine flags:
|
||||
|
@ -76,16 +76,16 @@ enum lsquic_version
|
|||
#define LSQUIC_EXPERIMENTAL_Q098 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IETF QUIC Draft-24
|
||||
*/
|
||||
LSQVER_ID24,
|
||||
|
||||
/**
|
||||
* IETF QUIC Draft-25
|
||||
*/
|
||||
LSQVER_ID25,
|
||||
|
||||
/**
|
||||
* IETF QUIC Draft-27
|
||||
*/
|
||||
LSQVER_ID27,
|
||||
|
||||
/**
|
||||
* Special version to trigger version negotiation.
|
||||
* [draft-ietf-quic-transport-11], Section 3.
|
||||
|
@ -96,7 +96,7 @@ enum lsquic_version
|
|||
};
|
||||
|
||||
/**
|
||||
* We currently support versions 43, 46, 50, Draft-24, and Draft-25
|
||||
* We currently support versions 43, 46, 50, Draft-25, and Draft-27.
|
||||
* @see lsquic_version
|
||||
*/
|
||||
#define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1)
|
||||
|
@ -113,10 +113,10 @@ enum lsquic_version
|
|||
|
||||
#define LSQUIC_GQUIC_HEADER_VERSIONS (1 << LSQVER_043)
|
||||
|
||||
#define LSQUIC_IETF_VERSIONS ((1 << LSQVER_ID24) | (1 << LSQVER_ID25) \
|
||||
#define LSQUIC_IETF_VERSIONS ((1 << LSQVER_ID25) | (1 << LSQVER_ID27) \
|
||||
| (1 << LSQVER_VERNEG))
|
||||
|
||||
#define LSQUIC_IETF_DRAFT_VERSIONS ((1 << LSQVER_ID24) | (1 << LSQVER_ID25) \
|
||||
#define LSQUIC_IETF_DRAFT_VERSIONS ((1 << LSQVER_ID25) | (1 << LSQVER_ID27) \
|
||||
| (1 << LSQVER_VERNEG))
|
||||
|
||||
enum lsquic_hsk_status
|
||||
|
|
|
@ -26,7 +26,6 @@ SET(lsquic_STAT_SRCS
|
|||
lsquic_frame_reader.c
|
||||
lsquic_frame_writer.c
|
||||
lsquic_full_conn.c
|
||||
lsquic_full_conn_id24.c
|
||||
lsquic_full_conn_ietf.c
|
||||
lsquic_global.c
|
||||
lsquic_handshake.c
|
||||
|
|
|
@ -31,7 +31,6 @@ 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 \
|
||||
|
|
|
@ -40,8 +40,6 @@ const char *const lsquic_alid2str[] =
|
|||
[AL_RETX_APP] = "RETX_APP",
|
||||
[AL_PING] = "PING",
|
||||
[AL_IDLE] = "IDLE",
|
||||
[AL_ACK_INIT] = "ACK_INIT",
|
||||
[AL_ACK_HSK] = "ACK_HSK",
|
||||
[AL_ACK_APP] = "ACK_APP",
|
||||
[AL_RET_CIDS] = "RET_CIDS",
|
||||
[AL_CID_THROT] = "CID_THROT",
|
||||
|
|
|
@ -27,10 +27,7 @@ enum alarm_id {
|
|||
AL_RETX_APP = AL_RETX_INIT + PNS_APP,
|
||||
AL_PING,
|
||||
AL_IDLE,
|
||||
/* TODO: remove AL_ACK_INIT and AL_ACK_HSK when LSQVER_ID24 is removed */
|
||||
AL_ACK_INIT,
|
||||
AL_ACK_HSK = AL_ACK_INIT + PNS_HSK,
|
||||
AL_ACK_APP = AL_ACK_INIT + PNS_APP,
|
||||
AL_ACK_APP,
|
||||
AL_RET_CIDS,
|
||||
AL_CID_THROT,
|
||||
AL_PATH_CHAL,
|
||||
|
@ -48,8 +45,6 @@ enum alarm_id_bit {
|
|||
ALBIT_RETX_HSK = 1 << AL_RETX_HSK,
|
||||
ALBIT_RETX_APP = 1 << AL_RETX_APP,
|
||||
ALBIT_ACK_APP = 1 << AL_ACK_APP,
|
||||
ALBIT_ACK_INIT = 1 << AL_ACK_INIT,
|
||||
ALBIT_ACK_HSK = 1 << AL_ACK_HSK,
|
||||
ALBIT_PING = 1 << AL_PING,
|
||||
ALBIT_IDLE = 1 << AL_IDLE,
|
||||
ALBIT_RET_CIDS = 1 << AL_RET_CIDS,
|
||||
|
|
|
@ -328,8 +328,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_ID24 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||
ver == LSQVER_ID25 ? &lsquic_enc_session_common_ietf_v1 : \
|
||||
ver == LSQVER_ID27 ? &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 )
|
||||
|
|
|
@ -71,9 +71,9 @@ static const struct alpn_map {
|
|||
enum lsquic_version version;
|
||||
const unsigned char *alpn;
|
||||
} s_alpns[] = {
|
||||
{ LSQVER_ID24, (unsigned char *) "\x05h3-24", },
|
||||
{ LSQVER_ID25, (unsigned char *) "\x05h3-25", },
|
||||
{ LSQVER_VERNEG, (unsigned char *) "\x05h3-25", },
|
||||
{ LSQVER_ID27, (unsigned char *) "\x05h3-27", },
|
||||
{ LSQVER_VERNEG, (unsigned char *) "\x05h3-27", },
|
||||
};
|
||||
|
||||
struct enc_sess_iquic;
|
||||
|
@ -546,12 +546,6 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
| (1 << TPI_MAX_PACKET_SIZE)
|
||||
| (1 << TPI_ACTIVE_CONNECTION_ID_LIMIT)
|
||||
;
|
||||
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_set & (1 << TPI_PREFERRED_ADDRESS));
|
||||
}
|
||||
if (!settings->es_allow_migration)
|
||||
params.tp_set |= 1 << TPI_DISABLE_ACTIVE_MIGRATION;
|
||||
if (settings->es_ql_bits)
|
||||
|
@ -565,7 +559,8 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
params.tp_set |= 1 << TPI_MIN_ACK_DELAY;
|
||||
}
|
||||
|
||||
len = lsquic_tp_encode(¶ms, enc_sess->esi_flags & ESI_SERVER, buf, bufsz);
|
||||
len = (enc_sess->esi_conn->cn_version == LSQVER_ID25 ? lsquic_tp_encode_id25 :
|
||||
lsquic_tp_encode)(¶ms, enc_sess->esi_flags & ESI_SERVER, buf, bufsz);
|
||||
if (len >= 0)
|
||||
LSQ_DEBUG("generated transport parameters buffer of %d bytes", len);
|
||||
else
|
||||
|
@ -1460,7 +1455,8 @@ get_peer_transport_params (struct enc_sess_iquic *enc_sess)
|
|||
}
|
||||
|
||||
LSQ_DEBUG("have peer transport parameters (%zu bytes)", bufsz);
|
||||
if (0 > lsquic_tp_decode(params_buf, bufsz,
|
||||
if (0 > (enc_sess->esi_conn->cn_version == LSQVER_ID25
|
||||
? lsquic_tp_decode_id25 : lsquic_tp_decode)(params_buf, bufsz,
|
||||
!(enc_sess->esi_flags & ESI_SERVER),
|
||||
trans_params))
|
||||
{
|
||||
|
@ -2674,7 +2670,8 @@ static void
|
|||
chsk_ietf_on_close (struct lsquic_stream *stream, lsquic_stream_ctx_t *ctx)
|
||||
{
|
||||
struct enc_sess_iquic *const enc_sess = (struct enc_sess_iquic *) ctx;
|
||||
LSQ_DEBUG("crypto stream level %u is closed",
|
||||
if (enc_sess && enc_sess->esi_cryst_if)
|
||||
LSQ_DEBUG("crypto stream level %u is closed",
|
||||
(unsigned) enc_sess->esi_cryst_if->csi_enc_level(stream));
|
||||
}
|
||||
|
||||
|
|
|
@ -900,12 +900,7 @@ 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)
|
||||
{
|
||||
if (mini_conn->cn_version == LSQVER_ID24)
|
||||
ctor = lsquic_id24_full_conn_server_new;
|
||||
else
|
||||
ctor = lsquic_ietf_full_conn_server_new;
|
||||
}
|
||||
ctor = lsquic_ietf_full_conn_server_new;
|
||||
else
|
||||
ctor = lsquic_gquic_full_conn_server_new;
|
||||
|
||||
|
@ -1562,16 +1557,9 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version,
|
|||
else
|
||||
versions = 1u << version;
|
||||
if (versions & LSQUIC_IETF_VERSIONS)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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,
|
||||
|
|
|
@ -21,14 +21,6 @@ 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 */,
|
||||
|
@ -44,11 +36,6 @@ 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
|
@ -1341,8 +1341,7 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
|
|||
|
||||
assert(mini_conn->cn_flags & LSCONN_HANDSHAKE_DONE);
|
||||
conn->ifc_conn.cn_flags |= LSCONN_HANDSHAKE_DONE;
|
||||
if (mini_conn->cn_version > LSQVER_ID24
|
||||
&& !(imc->imc_flags & IMC_HSK_DONE_SENT))
|
||||
if (!(imc->imc_flags & IMC_HSK_DONE_SENT))
|
||||
{
|
||||
LSQ_DEBUG("HANDSHAKE_DONE not yet sent, will process CRYPTO frames");
|
||||
conn->ifc_flags |= IFC_PROC_CRYPTO;
|
||||
|
@ -1559,8 +1558,6 @@ generate_ack_frame_for_pns (struct ietf_full_conn *conn,
|
|||
conn->ifc_n_slack_all = 0;
|
||||
lsquic_alarmset_unset(&conn->ifc_alset, AL_ACK_APP);
|
||||
}
|
||||
else
|
||||
assert(!lsquic_alarmset_is_set(&conn->ifc_alset, AL_ACK_INIT + pns));
|
||||
lsquic_send_ctl_sanity_check(&conn->ifc_send_ctl);
|
||||
LSQ_DEBUG("%s ACK state reset", lsquic_pns2str[pns]);
|
||||
|
||||
|
@ -3010,8 +3007,7 @@ handshake_ok (struct lsquic_conn *lconn)
|
|||
conn->ifc_ping_period = 0;
|
||||
LSQ_DEBUG("PING period is set to %"PRIu64" usec", conn->ifc_ping_period);
|
||||
|
||||
if (conn->ifc_conn.cn_version > LSQVER_ID24
|
||||
&& conn->ifc_settings->es_delayed_acks
|
||||
if (conn->ifc_settings->es_delayed_acks
|
||||
&& (params->tp_set & (1 << TPI_MIN_ACK_DELAY)))
|
||||
{
|
||||
LSQ_DEBUG("delayed ACKs enabled");
|
||||
|
@ -3265,11 +3261,11 @@ ietf_full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Generate header block. Using it, we will search for a duplicate push
|
||||
* promise. If not found, it will be copied to a new push_promise object.
|
||||
/* Generate header block in cheap 4K memory. It it will be copied to
|
||||
* a new push_promise object.
|
||||
*/
|
||||
p = header_block_buf;
|
||||
end = header_block_buf + 0x1000 - 1; /* Save one byte for key type */
|
||||
end = header_block_buf + 0x1000;
|
||||
pseudo_headers[0].name. iov_base = ":method";
|
||||
pseudo_headers[0].name. iov_len = 7;
|
||||
pseudo_headers[0].value.iov_base = "GET";
|
||||
|
@ -3326,18 +3322,6 @@ ietf_full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset,
|
|||
}
|
||||
LSQ_DEBUG("generated push promise header block of %ld bytes",
|
||||
(long) (p - header_block_buf));
|
||||
*p++ = PPKT_CONTENT;
|
||||
|
||||
el = lsquic_hash_find(conn->ifc_pub.u.ietf.promises,
|
||||
header_block_buf, p - header_block_buf);
|
||||
if (el)
|
||||
{
|
||||
lsquic_mm_put_4k(conn->ifc_pub.mm, header_block_buf);
|
||||
promise = lsquic_hashelem_getdata(el);
|
||||
LSQ_DEBUG("found push promise %"PRIu64", will issue a duplicate",
|
||||
promise->pp_id);
|
||||
return lsquic_stream_duplicate_push(dep_stream, promise->pp_id);
|
||||
}
|
||||
|
||||
own_hset = !hset;
|
||||
if (!hset)
|
||||
|
@ -3358,6 +3342,7 @@ ietf_full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset,
|
|||
if (!hset)
|
||||
{
|
||||
LSQ_INFO("header set ctor failure");
|
||||
lsquic_mm_put_4k(conn->ifc_pub.mm, header_block_buf);
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < n_header_sets; ++i)
|
||||
|
@ -3439,13 +3424,12 @@ ietf_full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset,
|
|||
memset(promise, 0, sizeof(*promise));
|
||||
promise->pp_refcnt = 1; /* This function itself keeps a reference */
|
||||
memcpy(promise->pp_content_buf, header_block_buf, p - header_block_buf);
|
||||
promise->pp_content_len = p - header_block_buf - 1;
|
||||
promise->pp_content_len = p - header_block_buf;
|
||||
promise->pp_id = conn->ifc_u.ser.ifser_next_push_id++;
|
||||
lsquic_mm_put_4k(conn->ifc_pub.mm, header_block_buf);
|
||||
|
||||
promise->pp_u_id.buf[8] = PPKT_ID;
|
||||
el = lsquic_hash_insert(conn->ifc_pub.u.ietf.promises,
|
||||
promise->pp_u_id.buf, sizeof(promise->pp_u_id.buf), promise,
|
||||
&promise->pp_id, sizeof(promise->pp_id), promise,
|
||||
&promise->pp_hash_id);
|
||||
if (!el)
|
||||
{
|
||||
|
@ -3457,19 +3441,6 @@ ietf_full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset,
|
|||
free(uh);
|
||||
return -1;
|
||||
}
|
||||
el = lsquic_hash_insert(conn->ifc_pub.u.ietf.promises,
|
||||
promise->pp_content_buf, promise->pp_content_len + 1, promise,
|
||||
&promise->pp_hash_content);
|
||||
if (!el)
|
||||
{
|
||||
LSQ_WARN("cannot insert push promise (content)");
|
||||
undo_stream_creation(conn, pushed_stream);
|
||||
if (own_hset)
|
||||
conn->ifc_enpub->enp_hsi_if->hsi_discard_header_set(hset);
|
||||
lsquic_pp_put(promise, conn->ifc_pub.u.ietf.promises);
|
||||
free(uh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != lsquic_stream_push_promise(dep_stream, promise))
|
||||
{
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */
|
||||
/*
|
||||
* lsquic_hq.h -- HTTP over QUIC (HQ) types
|
||||
* lsquic_hq.h -- HTTP/3 (originally "HTTP over QUIC" or HQ) types
|
||||
*/
|
||||
|
||||
#ifndef LSQUIC_HQ_H
|
||||
#define LSQUIC_HQ_H 1
|
||||
|
||||
/* [draft-ietf-quic-http-15] Section 4 */
|
||||
/* [draft-ietf-quic-http-27] Section 11.2.1 */
|
||||
enum hq_frame_type
|
||||
{
|
||||
HQFT_DATA = 0,
|
||||
|
@ -16,7 +16,6 @@ enum hq_frame_type
|
|||
HQFT_PUSH_PROMISE = 5,
|
||||
HQFT_GOAWAY = 7,
|
||||
HQFT_MAX_PUSH_ID = 0xD,
|
||||
HQFT_DUPLICATE_PUSH = 0xE,
|
||||
/* This frame is made up and its type is never written to stream.
|
||||
* Nevertheless, just to be on the safe side, give it a value as
|
||||
* described in [draft-ietf-quic-http-20] Section 4.2.10.
|
||||
|
|
|
@ -1689,13 +1689,10 @@ ietf_mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now)
|
|||
}
|
||||
else if (conn->imc_flags & IMC_HSK_OK)
|
||||
{
|
||||
if (conn->imc_conn.cn_version > LSQVER_ID24)
|
||||
{
|
||||
if (lconn->cn_esf.i->esfi_in_init(lconn->cn_enc_session))
|
||||
LSQ_DEBUG("still in init, defer HANDSHAKE_DONE");
|
||||
else if (0 != imico_generate_handshake_done(conn))
|
||||
goto close_on_error;
|
||||
}
|
||||
if (lconn->cn_esf.i->esfi_in_init(lconn->cn_enc_session))
|
||||
LSQ_DEBUG("still in init, defer HANDSHAKE_DONE");
|
||||
else if (0 != imico_generate_handshake_done(conn))
|
||||
goto close_on_error;
|
||||
tick |= TICK_PROMOTE;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,7 +316,6 @@ struct parse_funcs
|
|||
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) ( \
|
||||
|
@ -326,8 +325,6 @@ 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 */
|
||||
|
|
|
@ -1117,85 +1117,6 @@ ietf_v1_parse_frame_type (const unsigned char *buf, size_t len)
|
|||
}
|
||||
|
||||
|
||||
static enum quic_frame_type
|
||||
ietf_id24_parse_frame_type (const unsigned char *buf, size_t len)
|
||||
{
|
||||
/* This one does not have QUIC_FRAME_HANDSHAKE_DONE */
|
||||
static const enum quic_frame_type byte2type[0x40] =
|
||||
{
|
||||
[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,
|
||||
};
|
||||
|
||||
if (len > 1 && buf[0] < 0x40)
|
||||
return byte2type[buf[0]];
|
||||
else
|
||||
return QUIC_FRAME_INVALID;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
ietf_v1_path_chal_frame_size (void)
|
||||
{
|
||||
|
@ -1770,7 +1691,7 @@ lsquic_ietf_v1_parse_packet_in_long_begin (struct lsquic_packet_in *packet_in,
|
|||
const unsigned char *const end = p + length;
|
||||
lsquic_ver_tag_t tag;
|
||||
enum header_type header_type;
|
||||
unsigned dcil, scil, odcil;
|
||||
unsigned dcil, scil;
|
||||
int verneg, r;
|
||||
unsigned char first_byte;
|
||||
uint64_t payload_len, token_len;
|
||||
|
@ -1865,32 +1786,18 @@ lsquic_ietf_v1_parse_packet_in_long_begin (struct lsquic_packet_in *packet_in,
|
|||
case HETY_RETRY:
|
||||
if (p >= end)
|
||||
return -1;
|
||||
if (LSQVER_ID24 == lsquic_tag2ver(tag))
|
||||
{
|
||||
odcil = *p++;
|
||||
if (p + odcil > end || odcil > MAX_CID_LEN)
|
||||
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_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 */
|
||||
}
|
||||
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;
|
||||
|
@ -2165,22 +2072,6 @@ ietf_v1_parse_ack_frequency_frame (const unsigned char *buf, size_t buf_len,
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_id24_gen_ack_frequency_frame (unsigned char *buf, size_t buf_len,
|
||||
uint64_t seqno, uint64_t pack_tol, uint64_t upd_mad)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ietf_id24_parse_ack_frequency_frame (const unsigned char *buf, size_t buf_len,
|
||||
uint64_t *seqno, uint64_t *pack_tol, uint64_t *upd_mad)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
ietf_v1_ack_frequency_frame_size (uint64_t seqno, uint64_t pack_tol,
|
||||
uint64_t upd_mad)
|
||||
|
@ -2197,93 +2088,6 @@ ietf_v1_handshake_done_frame_size (void)
|
|||
}
|
||||
|
||||
|
||||
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,
|
||||
.pf_gen_ack_frequency_frame = ietf_id24_gen_ack_frequency_frame,
|
||||
.pf_parse_ack_frequency_frame = ietf_id24_parse_ack_frequency_frame,
|
||||
.pf_ack_frequency_frame_size = ietf_v1_ack_frequency_frame_size,
|
||||
};
|
||||
|
||||
|
||||
const struct parse_funcs lsquic_parse_funcs_ietf_v1 =
|
||||
{
|
||||
.pf_gen_reg_pkt_header = ietf_v1_gen_reg_pkt_header,
|
||||
|
|
|
@ -355,7 +355,7 @@ prq_new_req (struct pr_queue *prq, enum packet_req_type type,
|
|||
version = lsquic_tag2ver(ver_tag);
|
||||
}
|
||||
else /* Got to set it to something sensible... */
|
||||
version = LSQVER_ID24;
|
||||
version = LSQVER_ID25;
|
||||
|
||||
lsquic_scid_from_packet_in(packet_in, &scid);
|
||||
return lsquic_prq_new_req(prq, type, flags, version, packet_in->pi_data_sz,
|
||||
|
|
|
@ -6,12 +6,6 @@ struct lsquic_hash_elem;
|
|||
struct lsquic_stream;
|
||||
|
||||
|
||||
enum push_promise_key_type {
|
||||
PPKT_ID,
|
||||
PPKT_CONTENT,
|
||||
};
|
||||
|
||||
|
||||
struct push_promise
|
||||
{
|
||||
/* A push promise is associated with a single stream, while a stream can
|
||||
|
@ -21,19 +15,10 @@ struct push_promise
|
|||
* frames can be sent out.
|
||||
*/
|
||||
SLIST_ENTRY(push_promise) pp_next;
|
||||
/* Push promises are stored in the same hash and can be searched either
|
||||
* by ID or by content. To differentiate the two keys, the key type is
|
||||
* appended at the end PPKT_ID or PPKT_CONTENT.
|
||||
*/
|
||||
struct lsquic_hash_elem pp_hash_id,
|
||||
pp_hash_content;
|
||||
union {
|
||||
uint64_t id;
|
||||
unsigned char buf[9];
|
||||
} pp_u_id;
|
||||
#define pp_id pp_u_id.id
|
||||
/* Push promises are stored a hash and can be searched by ID */
|
||||
struct lsquic_hash_elem pp_hash_id;
|
||||
uint64_t pp_id;
|
||||
struct lsquic_stream *pp_pushed_stream;
|
||||
/* This does not include the last key-type byte: */
|
||||
size_t pp_content_len;
|
||||
/* Number of streams holding a reference to this push promise. When this
|
||||
* value becomes zero, the push promise is destroyed. See lsquic_pp_put().
|
||||
|
@ -64,7 +49,7 @@ struct push_promise
|
|||
unsigned pp_write_off;
|
||||
unsigned char pp_encoded_push_id[8];
|
||||
/* The content buffer is the header block: it does not include Header
|
||||
* Block Prefix. It is followed by one-byte key type PPKT_CONTENT.
|
||||
* Block Prefix.
|
||||
*/
|
||||
unsigned char pp_content_buf[0];
|
||||
};
|
||||
|
@ -77,9 +62,6 @@ struct push_promise
|
|||
LSQ_DEBUG("destroy push promise %"PRIu64, (promise_)->pp_id); \
|
||||
if ((promise_)->pp_hash_id.qhe_flags & QHE_HASHED) \
|
||||
lsquic_hash_erase(all_promises_, &(promise_)->pp_hash_id); \
|
||||
if ((promise_)->pp_hash_content.qhe_flags & QHE_HASHED) \
|
||||
lsquic_hash_erase(all_promises_, \
|
||||
&(promise_)->pp_hash_content); \
|
||||
free(promise); \
|
||||
} \
|
||||
} \
|
||||
|
|
|
@ -147,9 +147,6 @@ stream_write_buf (struct lsquic_stream *stream, const void *buf, size_t sz);
|
|||
static size_t
|
||||
active_hq_frame_sizes (const struct lsquic_stream *);
|
||||
|
||||
static void
|
||||
on_write_dp_wrapper (struct lsquic_stream *, lsquic_stream_ctx_t *);
|
||||
|
||||
static void
|
||||
on_write_pp_wrapper (struct lsquic_stream *, lsquic_stream_ctx_t *);
|
||||
|
||||
|
@ -1986,8 +1983,6 @@ static void
|
|||
assert(stream->stream_flags & STREAM_PUSHING);
|
||||
if (stream_is_pushing_promise(stream))
|
||||
return on_write_pp_wrapper;
|
||||
else if (stream->sm_dup_push_off < stream->sm_dup_push_len)
|
||||
return on_write_dp_wrapper;
|
||||
else
|
||||
return stream->stream_if->on_write;
|
||||
}
|
||||
|
@ -4081,7 +4076,6 @@ update_type_hist_and_check (const struct lsquic_stream *stream,
|
|||
code = CODE_DATA;
|
||||
break;
|
||||
case HQFT_PUSH_PROMISE:
|
||||
case HQFT_DUPLICATE_PUSH:
|
||||
/* [draft-ietf-quic-http-24], Section 7 */
|
||||
if ((stream->id & SIT_MASK) == SIT_BIDI_CLIENT
|
||||
&& !(stream->sm_bflags & SMBF_SERVER))
|
||||
|
@ -4566,128 +4560,6 @@ lsquic_stream_can_push (const struct lsquic_stream *stream)
|
|||
}
|
||||
|
||||
|
||||
static size_t
|
||||
dp_reader_read (void *lsqr_ctx, void *buf, size_t count)
|
||||
{
|
||||
struct lsquic_stream *const stream = lsqr_ctx;
|
||||
unsigned char *dst = buf;
|
||||
unsigned char *const end = buf + count;
|
||||
size_t len;
|
||||
|
||||
len = MIN((size_t) (stream->sm_dup_push_len - stream->sm_dup_push_off),
|
||||
(size_t) (end - dst));
|
||||
memcpy(dst, stream->sm_dup_push_buf + stream->sm_dup_push_off, len);
|
||||
stream->sm_dup_push_off += len;
|
||||
|
||||
if (stream->sm_dup_push_len == stream->sm_dup_push_off)
|
||||
LSQ_DEBUG("finish writing duplicate push");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
dp_reader_size (void *lsqr_ctx)
|
||||
{
|
||||
struct lsquic_stream *const stream = lsqr_ctx;
|
||||
|
||||
return stream->sm_dup_push_len - stream->sm_dup_push_off;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_dp_reader (struct lsquic_stream *stream, struct lsquic_reader *reader)
|
||||
{
|
||||
reader->lsqr_read = dp_reader_read;
|
||||
reader->lsqr_size = dp_reader_size;
|
||||
reader->lsqr_ctx = stream;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_write_dp_wrapper (struct lsquic_stream *stream, lsquic_stream_ctx_t *h)
|
||||
{
|
||||
struct lsquic_reader dp_reader;
|
||||
ssize_t nw;
|
||||
int want_write;
|
||||
|
||||
assert(stream->sm_dup_push_off < stream->sm_dup_push_len);
|
||||
|
||||
init_dp_reader(stream, &dp_reader);
|
||||
nw = stream_write(stream, &dp_reader);
|
||||
if (nw > 0)
|
||||
{
|
||||
LSQ_DEBUG("wrote %zd bytes more of duplicate push (%s)",
|
||||
nw, stream->sm_dup_push_off == stream->sm_dup_push_len ?
|
||||
"done" : "not done");
|
||||
if (stream->sm_dup_push_off == stream->sm_dup_push_len)
|
||||
{
|
||||
/* Restore want_write flag */
|
||||
want_write = !!(stream->sm_qflags & SMQF_WANT_WRITE);
|
||||
if (want_write != stream->sm_saved_want_write)
|
||||
(void) lsquic_stream_wantwrite(stream,
|
||||
stream->sm_saved_want_write);
|
||||
}
|
||||
}
|
||||
else if (nw < 0)
|
||||
{
|
||||
LSQ_WARN("could not write duplicate push (wrapper)");
|
||||
/* XXX What should happen if we hit an error? TODO */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lsquic_stream_duplicate_push (struct lsquic_stream *stream, uint64_t push_id)
|
||||
{
|
||||
struct lsquic_reader dp_reader;
|
||||
unsigned bits, len;
|
||||
ssize_t nw;
|
||||
|
||||
assert(stream->sm_bflags & SMBF_IETF);
|
||||
assert(lsquic_stream_can_push(stream));
|
||||
|
||||
bits = vint_val2bits(push_id);
|
||||
len = 1 << bits;
|
||||
|
||||
if (!stream_activate_hq_frame(stream,
|
||||
stream->sm_payload + stream->sm_n_buffered, HQFT_DUPLICATE_PUSH,
|
||||
SHF_FIXED_SIZE, len))
|
||||
return -1;
|
||||
|
||||
stream->stream_flags |= STREAM_PUSHING;
|
||||
|
||||
stream->sm_dup_push_len = len;
|
||||
stream->sm_dup_push_off = 0;
|
||||
vint_write(stream->sm_dup_push_buf, push_id, bits, 1 << bits);
|
||||
|
||||
init_dp_reader(stream, &dp_reader);
|
||||
nw = stream_write(stream, &dp_reader);
|
||||
if (nw > 0)
|
||||
{
|
||||
if (stream->sm_dup_push_off == stream->sm_dup_push_len)
|
||||
LSQ_DEBUG("fully wrote DUPLICATE_PUSH %"PRIu64, push_id);
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("partially wrote DUPLICATE_PUSH %"PRIu64, push_id);
|
||||
stream->stream_flags |= STREAM_NOPUSH;
|
||||
stream->sm_saved_want_write =
|
||||
!!(stream->sm_qflags & SMQF_WANT_WRITE);
|
||||
stream_wantwrite(stream, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nw < 0)
|
||||
LSQ_WARN("failure writing DUPLICATE_PUSH");
|
||||
stream->stream_flags |= STREAM_NOPUSH;
|
||||
stream->stream_flags &= ~STREAM_PUSHING;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
pp_reader_read (void *lsqr_ctx, void *buf, size_t count)
|
||||
{
|
||||
|
|
|
@ -341,10 +341,6 @@ struct lsquic_stream
|
|||
signed char sm_saved_want_write;
|
||||
signed char sm_has_frame;
|
||||
|
||||
unsigned char sm_dup_push_off;
|
||||
unsigned char sm_dup_push_len;
|
||||
unsigned char sm_dup_push_buf[8];
|
||||
|
||||
#if LSQUIC_KEEP_STREAM_HISTORY
|
||||
sm_hist_idx_t sm_hist_idx;
|
||||
#endif
|
||||
|
@ -592,9 +588,6 @@ lsquic_stream_qdec_unblocked (struct lsquic_stream *);
|
|||
int
|
||||
lsquic_stream_can_push (const struct lsquic_stream *);
|
||||
|
||||
int
|
||||
lsquic_stream_duplicate_push (struct lsquic_stream *, uint64_t push_id);
|
||||
|
||||
int
|
||||
lsquic_stream_push_promise (struct lsquic_stream *, struct push_promise *);
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ tpi_val_2_enum (uint64_t tpi_val)
|
|||
}
|
||||
|
||||
|
||||
static const unsigned short enum_2_tpi_val[LAST_TPI + 1] =
|
||||
static const unsigned enum_2_tpi_val[LAST_TPI + 1] =
|
||||
{
|
||||
[TPI_ORIGINAL_CONNECTION_ID] = 0x0,
|
||||
[TPI_MAX_IDLE_TIMEOUT] = 0x1,
|
||||
|
@ -183,6 +183,500 @@ lsquic_tp_has_pref_ipv6 (const struct transport_params *params)
|
|||
int
|
||||
lsquic_tp_encode (const struct transport_params *params, int is_server,
|
||||
unsigned char *const buf, size_t bufsz)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t need;
|
||||
uint16_t u16;
|
||||
enum transport_param_id tpi;
|
||||
unsigned set;
|
||||
unsigned bits[LAST_TPI + 1][3 /* ID, length, value */];
|
||||
|
||||
need = 0;
|
||||
set = params->tp_set; /* Will turn bits off for default values */
|
||||
|
||||
if (is_server)
|
||||
{
|
||||
if (set & (1 << TPI_ORIGINAL_CONNECTION_ID))
|
||||
{
|
||||
bits[TPI_ORIGINAL_CONNECTION_ID][0]
|
||||
= vint_val2bits(enum_2_tpi_val[TPI_ORIGINAL_CONNECTION_ID]);
|
||||
#if __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
bits[TPI_ORIGINAL_CONNECTION_ID][1]
|
||||
= vint_val2bits(params->tp_original_cid.len);
|
||||
#if __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
need += (1 << bits[TPI_ORIGINAL_CONNECTION_ID][0])
|
||||
+ (1 << bits[TPI_ORIGINAL_CONNECTION_ID][1])
|
||||
+ params->tp_original_cid.len;
|
||||
}
|
||||
if (set & (1 << TPI_STATELESS_RESET_TOKEN))
|
||||
{
|
||||
bits[TPI_STATELESS_RESET_TOKEN][0]
|
||||
= vint_val2bits(enum_2_tpi_val[TPI_STATELESS_RESET_TOKEN]);
|
||||
bits[TPI_STATELESS_RESET_TOKEN][1]
|
||||
= vint_val2bits(sizeof(params->tp_stateless_reset_token));
|
||||
need += (1 << bits[TPI_STATELESS_RESET_TOKEN][0])
|
||||
+ (1 << bits[TPI_STATELESS_RESET_TOKEN][1])
|
||||
+ sizeof(params->tp_stateless_reset_token);
|
||||
}
|
||||
if (set & (1 << TPI_PREFERRED_ADDRESS))
|
||||
{
|
||||
bits[TPI_PREFERRED_ADDRESS][0]
|
||||
= vint_val2bits(enum_2_tpi_val[TPI_PREFERRED_ADDRESS]);
|
||||
bits[TPI_PREFERRED_ADDRESS][1] = vint_val2bits(
|
||||
preferred_address_size(params));
|
||||
need += (1 << bits[TPI_PREFERRED_ADDRESS][0])
|
||||
+ (1 << bits[TPI_PREFERRED_ADDRESS][1])
|
||||
+ preferred_address_size(params);
|
||||
}
|
||||
}
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
else if (set & (1 << TPI_QUANTUM_READINESS))
|
||||
{
|
||||
bits[TPI_QUANTUM_READINESS][0]
|
||||
= vint_val2bits(enum_2_tpi_val[TPI_QUANTUM_READINESS]);
|
||||
bits[TPI_QUANTUM_READINESS][1] = vint_val2bits(QUANTUM_READY_SZ);
|
||||
need += (1 << bits[TPI_QUANTUM_READINESS][0])
|
||||
+ (1 << bits[TPI_QUANTUM_READINESS][1])
|
||||
+ QUANTUM_READY_SZ;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
|
||||
if (set & (1 << tpi))
|
||||
{
|
||||
if (tpi > MAX_NUM_WITH_DEF_TPI
|
||||
|| params->tp_numerics[tpi] != def_vals[tpi])
|
||||
{
|
||||
if (params->tp_numerics[tpi] >= min_vals[tpi]
|
||||
&& params->tp_numerics[tpi] <= max_vals[tpi])
|
||||
{
|
||||
bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]);
|
||||
bits[tpi][2] = vint_val2bits(params->tp_numerics[tpi]);
|
||||
bits[tpi][1] = vint_val2bits(bits[tpi][2]);
|
||||
need += (1 << bits[tpi][0])
|
||||
+ (1 << bits[tpi][1])
|
||||
+ (1 << bits[tpi][2]);
|
||||
}
|
||||
else if (params->tp_numerics[tpi] > max_vals[tpi])
|
||||
{
|
||||
LSQ_DEBUG("numeric value of %s is too large (%"PRIu64" vs "
|
||||
"maximum of %"PRIu64")", tpi2str[tpi],
|
||||
params->tp_numerics[tpi], max_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("numeric value of %s is too small (%"PRIu64" vs "
|
||||
"minimum " "of %"PRIu64")",
|
||||
tpi2str[tpi], params->tp_numerics[tpi], min_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
set &= ~(1 << tpi); /* Don't write default value */
|
||||
}
|
||||
|
||||
for (; tpi <= MAX_EMPTY_TPI; ++tpi)
|
||||
if (set & (1 << tpi))
|
||||
{
|
||||
bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]);
|
||||
need += (1 << bits[tpi][0]) + 1 /* Zero length byte */;
|
||||
}
|
||||
|
||||
if (need > bufsz || need > UINT16_MAX)
|
||||
{
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
|
||||
#define WRITE_TO_P(src, len) do { \
|
||||
memcpy(p, src, len); \
|
||||
p += len; \
|
||||
} while (0)
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define WRITE_UINT_TO_P(val, width) do { \
|
||||
u##width = bswap_##width(val); \
|
||||
WRITE_TO_P(&u##width, sizeof(u##width)); \
|
||||
} while (0)
|
||||
#else
|
||||
#define WRITE_UINT_TO_P(val, width) do { \
|
||||
u##width = val; \
|
||||
WRITE_TO_P(&u##width, sizeof(u##width)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
for (tpi = 0; tpi <= LAST_TPI; ++tpi)
|
||||
if (set & (1 << tpi))
|
||||
{
|
||||
vint_write(p, enum_2_tpi_val[tpi], bits[tpi][0],
|
||||
1 << bits[tpi][0]);
|
||||
p += 1 << bits[tpi][0];
|
||||
switch (tpi)
|
||||
{
|
||||
case TPI_MAX_IDLE_TIMEOUT:
|
||||
case TPI_MAX_PACKET_SIZE:
|
||||
case TPI_INIT_MAX_DATA:
|
||||
case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL:
|
||||
case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE:
|
||||
case TPI_INIT_MAX_STREAM_DATA_UNI:
|
||||
case TPI_INIT_MAX_STREAMS_BIDI:
|
||||
case TPI_INIT_MAX_STREAMS_UNI:
|
||||
case TPI_ACK_DELAY_EXPONENT:
|
||||
case TPI_MAX_ACK_DELAY:
|
||||
case TPI_ACTIVE_CONNECTION_ID_LIMIT:
|
||||
case TPI_LOSS_BITS:
|
||||
case TPI_MIN_ACK_DELAY:
|
||||
vint_write(p, 1 << bits[tpi][2], bits[tpi][1],
|
||||
1 << bits[tpi][1]);
|
||||
p += 1 << bits[tpi][1];
|
||||
vint_write(p, params->tp_numerics[tpi], bits[tpi][2],
|
||||
1 << bits[tpi][2]);
|
||||
p += 1 << bits[tpi][2];
|
||||
break;
|
||||
case TPI_ORIGINAL_CONNECTION_ID:
|
||||
vint_write(p, params->tp_original_cid.len, bits[tpi][1],
|
||||
1 << bits[tpi][1]);
|
||||
p += 1 << bits[tpi][1];
|
||||
WRITE_TO_P(params->tp_original_cid.idbuf,
|
||||
params->tp_original_cid.len);
|
||||
break;
|
||||
case TPI_STATELESS_RESET_TOKEN:
|
||||
vint_write(p, sizeof(params->tp_stateless_reset_token),
|
||||
bits[tpi][1], 1 << bits[tpi][1]);
|
||||
p += 1 << bits[tpi][1];
|
||||
WRITE_TO_P(params->tp_stateless_reset_token,
|
||||
sizeof(params->tp_stateless_reset_token));
|
||||
break;
|
||||
case TPI_PREFERRED_ADDRESS:
|
||||
vint_write(p, preferred_address_size(params),
|
||||
bits[tpi][1], 1 << bits[tpi][1]);
|
||||
p += 1 << bits[tpi][1];
|
||||
WRITE_UINT_TO_P(preferred_address_size(params), 16);
|
||||
WRITE_TO_P(¶ms->tp_preferred_address.ipv4_addr,
|
||||
sizeof(params->tp_preferred_address.ipv4_addr));
|
||||
WRITE_UINT_TO_P(params->tp_preferred_address.ipv4_port, 16);
|
||||
WRITE_TO_P(¶ms->tp_preferred_address.ipv6_addr,
|
||||
sizeof(params->tp_preferred_address.ipv6_addr));
|
||||
WRITE_UINT_TO_P(params->tp_preferred_address.ipv6_port, 16);
|
||||
*p++ = params->tp_preferred_address.cid.len;
|
||||
WRITE_TO_P(params->tp_preferred_address.cid.idbuf,
|
||||
params->tp_preferred_address.cid.len);
|
||||
WRITE_TO_P(params->tp_preferred_address.srst,
|
||||
sizeof(params->tp_preferred_address.srst));
|
||||
break;
|
||||
case TPI_DISABLE_ACTIVE_MIGRATION:
|
||||
*p++ = 0;
|
||||
break;
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
case TPI_QUANTUM_READINESS:
|
||||
vint_write(p, QUANTUM_READY_SZ,
|
||||
bits[tpi][1], 1 << bits[tpi][1]);
|
||||
p += 1 << bits[tpi][1];
|
||||
memset(p, 'Q', QUANTUM_READY_SZ);
|
||||
p += QUANTUM_READY_SZ;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
assert(buf + need == p);
|
||||
return (int) (p - buf);
|
||||
|
||||
#undef WRITE_TO_P
|
||||
#undef WRITE_UINT_TO_P
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
||||
int is_server,
|
||||
struct transport_params *params)
|
||||
{
|
||||
const unsigned char *p, *end, *q;
|
||||
uint64_t len, param_id;
|
||||
uint16_t tlen;
|
||||
enum transport_param_id tpi;
|
||||
unsigned set_of_ids;
|
||||
int s;
|
||||
|
||||
p = buf;
|
||||
end = buf + bufsz;
|
||||
|
||||
*params = TP_INITIALIZER();
|
||||
|
||||
#define EXPECT_LEN(expected_len) do { \
|
||||
if (expected_len != len) \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_AT_LEAST(expected_len) do { \
|
||||
if ((expected_len) > (uintptr_t) (p + len - q)) \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
set_of_ids = 0;
|
||||
while (p < end)
|
||||
{
|
||||
s = vint_read(p, end, ¶m_id);
|
||||
if (s < 0)
|
||||
return -1;
|
||||
p += s;
|
||||
s = vint_read(p, end, &len);
|
||||
if (s < 0)
|
||||
return -1;
|
||||
p += s;
|
||||
if ((ptrdiff_t) len > end - p)
|
||||
return -1;
|
||||
tpi = tpi_val_2_enum(param_id);
|
||||
if (tpi <= LAST_TPI)
|
||||
{
|
||||
if (set_of_ids & (1 << tpi))
|
||||
return -1;
|
||||
set_of_ids |= 1 << tpi;
|
||||
}
|
||||
switch (tpi)
|
||||
{
|
||||
case TPI_MAX_IDLE_TIMEOUT:
|
||||
case TPI_MAX_PACKET_SIZE:
|
||||
case TPI_INIT_MAX_DATA:
|
||||
case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL:
|
||||
case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE:
|
||||
case TPI_INIT_MAX_STREAM_DATA_UNI:
|
||||
case TPI_INIT_MAX_STREAMS_BIDI:
|
||||
case TPI_INIT_MAX_STREAMS_UNI:
|
||||
case TPI_ACK_DELAY_EXPONENT:
|
||||
case TPI_MAX_ACK_DELAY:
|
||||
case TPI_ACTIVE_CONNECTION_ID_LIMIT:
|
||||
case TPI_LOSS_BITS:
|
||||
case TPI_MIN_ACK_DELAY:
|
||||
switch (len)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
s = vint_read(p, p + len, ¶ms->tp_numerics[tpi]);
|
||||
if (s == (int) len)
|
||||
{
|
||||
if (params->tp_numerics[tpi] > max_vals[tpi])
|
||||
{
|
||||
LSQ_DEBUG("numeric value of %s is too large "
|
||||
"(%"PRIu64" vs maximum of %"PRIu64, tpi2str[tpi],
|
||||
params->tp_numerics[tpi], max_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
else if (params->tp_numerics[tpi] < min_vals[tpi])
|
||||
{
|
||||
LSQ_DEBUG("numeric value of %s is too small "
|
||||
"(%"PRIu64" vs minimum of %"PRIu64, tpi2str[tpi],
|
||||
params->tp_numerics[tpi], min_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("cannot read the value of numeric transport "
|
||||
"param %s of length %"PRIu64, tpi2str[tpi], len);
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
LSQ_DEBUG("invalid length=%"PRIu64" for numeric transport "
|
||||
"parameter %s", len, tpi2str[tpi]);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case TPI_DISABLE_ACTIVE_MIGRATION:
|
||||
EXPECT_LEN(0);
|
||||
break;
|
||||
case TPI_STATELESS_RESET_TOKEN:
|
||||
/* Client MUST not include reset token,
|
||||
* see [draft-ietf-quic-transport-11], Section 6.4.1
|
||||
*/
|
||||
if (!is_server)
|
||||
return -1;
|
||||
EXPECT_LEN(sizeof(params->tp_stateless_reset_token));
|
||||
memcpy(params->tp_stateless_reset_token, p,
|
||||
sizeof(params->tp_stateless_reset_token));
|
||||
break;
|
||||
case TPI_ORIGINAL_CONNECTION_ID:
|
||||
/* Client MUST not original connecti ID,
|
||||
* see [draft-ietf-quic-transport-15], Section 6.6.1
|
||||
*/
|
||||
if (!is_server)
|
||||
return -1;
|
||||
if (len > MAX_CID_LEN)
|
||||
return -1;
|
||||
memcpy(params->tp_original_cid.idbuf, p, len);
|
||||
params->tp_original_cid.len = len;
|
||||
break;
|
||||
case TPI_PREFERRED_ADDRESS:
|
||||
/* Client MUST not include preferred address,
|
||||
* see [draft-ietf-quic-transport-12], Section 6.4.1
|
||||
*/
|
||||
if (!is_server)
|
||||
return -1;
|
||||
q = p;
|
||||
EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_addr));
|
||||
memcpy(params->tp_preferred_address.ipv4_addr, q,
|
||||
sizeof(params->tp_preferred_address.ipv4_addr));
|
||||
q += sizeof(params->tp_preferred_address.ipv4_addr);
|
||||
EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_port));
|
||||
READ_UINT(params->tp_preferred_address.ipv4_port, 16, q, 2);
|
||||
q += 2;
|
||||
EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_addr));
|
||||
memcpy(params->tp_preferred_address.ipv6_addr, q,
|
||||
sizeof(params->tp_preferred_address.ipv6_addr));
|
||||
q += sizeof(params->tp_preferred_address.ipv6_addr);
|
||||
EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_port));
|
||||
READ_UINT(params->tp_preferred_address.ipv6_port, 16, q, 2);
|
||||
q += 2;
|
||||
EXPECT_AT_LEAST(1);
|
||||
tlen = *q;
|
||||
q += 1;
|
||||
if (tlen < 4 || tlen > MAX_CID_LEN)
|
||||
{
|
||||
LSQ_DEBUG("preferred server address contains invalid "
|
||||
"CID length of %"PRIu16" bytes", tlen);
|
||||
return -1;
|
||||
}
|
||||
EXPECT_AT_LEAST(tlen);
|
||||
memcpy(params->tp_preferred_address.cid.idbuf, q, tlen);
|
||||
params->tp_preferred_address.cid.len = tlen;
|
||||
q += tlen;
|
||||
EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.srst));
|
||||
memcpy(params->tp_preferred_address.srst, q,
|
||||
sizeof(params->tp_preferred_address.srst));
|
||||
q += sizeof(params->tp_preferred_address.srst);
|
||||
if (q != p + len)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
/* Do nothing: skip this transport parameter */
|
||||
break;
|
||||
}
|
||||
p += len;
|
||||
if (tpi <= LAST_TPI)
|
||||
{
|
||||
params->tp_set |= 1 << tpi;
|
||||
params->tp_decoded |= 1 << tpi;
|
||||
}
|
||||
}
|
||||
|
||||
if (p != end)
|
||||
return -1;
|
||||
|
||||
if ((params->tp_set & (1 << TPI_MIN_ACK_DELAY))
|
||||
&& params->tp_numerics[TPI_MIN_ACK_DELAY]
|
||||
> params->tp_numerics[TPI_MAX_ACK_DELAY] * 1000)
|
||||
{
|
||||
LSQ_DEBUG("min_ack_delay (%"PRIu64" usec) is larger than "
|
||||
"max_ack_delay (%"PRIu64" ms)",
|
||||
params->tp_numerics[TPI_MIN_ACK_DELAY],
|
||||
params->tp_numerics[TPI_MAX_ACK_DELAY]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) (end - buf);
|
||||
#undef EXPECT_LEN
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
|
||||
{
|
||||
char *const end = buf + sz;
|
||||
int nw;
|
||||
enum transport_param_id tpi;
|
||||
char tok_str[sizeof(params->tp_stateless_reset_token) * 2 + 1];
|
||||
char addr_str[INET6_ADDRSTRLEN];
|
||||
|
||||
for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
|
||||
if (params->tp_set & (1 << tpi))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "%.*s%s: %"PRIu64,
|
||||
(buf + sz > end) << 1, "; ", tpi2str[tpi],
|
||||
params->tp_numerics[tpi]);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
for (; tpi <= MAX_EMPTY_TPI; ++tpi)
|
||||
if (params->tp_set & (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "%.*s%s",
|
||||
(buf + sz > end) << 1, "; ", tpi2str[tpi]);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
if (params->tp_set & (1 << TPI_QUANTUM_READINESS))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "%.*s%s",
|
||||
(buf + sz > end) << 1, "; ", tpi2str[TPI_QUANTUM_READINESS]);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (params->tp_set & (1 << TPI_STATELESS_RESET_TOKEN))
|
||||
{
|
||||
lsquic_hexstr(params->tp_stateless_reset_token,
|
||||
sizeof(params->tp_stateless_reset_token), tok_str, sizeof(tok_str));
|
||||
nw = snprintf(buf, end - buf, "; stateless_reset_token: %s", tok_str);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
if (params->tp_set & (1 << TPI_ORIGINAL_CONNECTION_ID))
|
||||
{
|
||||
char cidbuf_[MAX_CID_LEN * 2 + 1];
|
||||
nw = snprintf(buf, end - buf, "; original DCID (ODCID): %"CID_FMT,
|
||||
CID_BITS(¶ms->tp_original_cid));
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
if (lsquic_tp_has_pref_ipv4(params))
|
||||
{
|
||||
if (inet_ntop(AF_INET, params->tp_preferred_address.ipv4_addr,
|
||||
addr_str, sizeof(addr_str)))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "; IPv4 preferred address: %s:%u",
|
||||
addr_str, params->tp_preferred_address.ipv4_port);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (lsquic_tp_has_pref_ipv6(params))
|
||||
{
|
||||
if (inet_ntop(AF_INET6, params->tp_preferred_address.ipv6_addr,
|
||||
addr_str, sizeof(addr_str)))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "; IPv6 preferred address: %s:%u",
|
||||
addr_str, params->tp_preferred_address.ipv6_port);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lsquic_tp_encode_id25 (const struct transport_params *params, int is_server,
|
||||
unsigned char *const buf, size_t bufsz)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t need = 2;
|
||||
|
@ -348,7 +842,7 @@ lsquic_tp_encode (const struct transport_params *params, int is_server,
|
|||
|
||||
|
||||
int
|
||||
lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
||||
lsquic_tp_decode_id25 (const unsigned char *const buf, size_t bufsz,
|
||||
int is_server,
|
||||
struct transport_params *params)
|
||||
{
|
||||
|
@ -543,86 +1037,3 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
|||
return (int) (end - buf);
|
||||
#undef EXPECT_LEN
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
|
||||
{
|
||||
char *const end = buf + sz;
|
||||
int nw;
|
||||
enum transport_param_id tpi;
|
||||
char tok_str[sizeof(params->tp_stateless_reset_token) * 2 + 1];
|
||||
char addr_str[INET6_ADDRSTRLEN];
|
||||
|
||||
for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
|
||||
if (params->tp_set & (1 << tpi))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "%.*s%s: %"PRIu64,
|
||||
(buf + sz > end) << 1, "; ", tpi2str[tpi],
|
||||
params->tp_numerics[tpi]);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
for (; tpi <= MAX_EMPTY_TPI; ++tpi)
|
||||
if (params->tp_set & (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "%.*s%s",
|
||||
(buf + sz > end) << 1, "; ", tpi2str[tpi]);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
if (params->tp_set & (1 << TPI_QUANTUM_READINESS))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "%.*s%s",
|
||||
(buf + sz > end) << 1, "; ", tpi2str[TPI_QUANTUM_READINESS]);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (params->tp_set & (1 << TPI_STATELESS_RESET_TOKEN))
|
||||
{
|
||||
lsquic_hexstr(params->tp_stateless_reset_token,
|
||||
sizeof(params->tp_stateless_reset_token), tok_str, sizeof(tok_str));
|
||||
nw = snprintf(buf, end - buf, "; stateless_reset_token: %s", tok_str);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
if (params->tp_set & (1 << TPI_ORIGINAL_CONNECTION_ID))
|
||||
{
|
||||
char cidbuf_[MAX_CID_LEN * 2 + 1];
|
||||
nw = snprintf(buf, end - buf, "; original DCID (ODCID): %"CID_FMT,
|
||||
CID_BITS(¶ms->tp_original_cid));
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
if (lsquic_tp_has_pref_ipv4(params))
|
||||
{
|
||||
if (inet_ntop(AF_INET, params->tp_preferred_address.ipv4_addr,
|
||||
addr_str, sizeof(addr_str)))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "; IPv4 preferred address: %s:%u",
|
||||
addr_str, params->tp_preferred_address.ipv4_port);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (lsquic_tp_has_pref_ipv6(params))
|
||||
{
|
||||
if (inet_ntop(AF_INET6, params->tp_preferred_address.ipv6_addr,
|
||||
addr_str, sizeof(addr_str)))
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "; IPv6 preferred address: %s:%u",
|
||||
addr_str, params->tp_preferred_address.ipv6_port);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,6 +134,14 @@ lsquic_tp_decode (const unsigned char *buf, size_t bufsz,
|
|||
int is_server,
|
||||
struct transport_params *);
|
||||
|
||||
int
|
||||
lsquic_tp_encode_id25 (const struct transport_params *, int is_server,
|
||||
unsigned char *buf, size_t bufsz);
|
||||
|
||||
int
|
||||
lsquic_tp_decode_id25 (const unsigned char *buf, size_t bufsz,
|
||||
int is_server, struct transport_params *);
|
||||
|
||||
void
|
||||
lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/* See [draft-ietf-quic-transport-11], section-7.1 */
|
||||
#define vint_val2bits(val) ( \
|
||||
(val >= (1 << 6)) + (val >= (1 << 14)) + (val >= (1 << 30)))
|
||||
((val) >= (1 << 6)) + ((val) >= (1 << 14)) + ((val) >= (1 << 30)))
|
||||
|
||||
#define vint_size(val) (1u << vint_val2bits(val))
|
||||
|
||||
|
|
|
@ -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_ID24] = { 0xFF, 0, 0, 24, },
|
||||
[LSQVER_ID25] = { 0xFF, 0, 0, 25, },
|
||||
[LSQVER_ID27] = { 0xFF, 0, 0, 27, },
|
||||
[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_ID24] = "FF000018",
|
||||
[LSQVER_ID25] = "FF000019",
|
||||
[LSQVER_ID27] = "FF00001B",
|
||||
[LSQVER_VERNEG] = "FAFAFAFA",
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ static int
|
|||
select_alpn (SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
||||
const unsigned char *in, unsigned int inlen, void *arg)
|
||||
{
|
||||
const unsigned char alpn[] = "\x5h3-24\x5h3-25";
|
||||
const unsigned char alpn[] = "\x5h3-25\x5h3-27";
|
||||
int r;
|
||||
|
||||
r = SSL_select_next_proto((unsigned char **) out, outlen, in, inlen,
|
||||
|
|
|
@ -179,7 +179,7 @@ run_test (const struct test *test)
|
|||
size_t sz;
|
||||
unsigned char buf[0x1000];
|
||||
|
||||
pf = select_pf_by_ver(LSQVER_ID24);
|
||||
pf = select_pf_by_ver(LSQVER_ID25);
|
||||
if (!test->skip_gen)
|
||||
{
|
||||
rechist.acki = &test->acki;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
static struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 0);
|
||||
|
||||
static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_ID24);
|
||||
static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_ID25);
|
||||
|
||||
|
||||
static void
|
||||
|
|
|
@ -33,7 +33,7 @@ struct test {
|
|||
static const struct test tests[] = {
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.pf = select_pf_by_ver(LSQVER_ID25),
|
||||
.offset = 0,
|
||||
.data_sz = 10,
|
||||
.data = "0123456789",
|
||||
|
@ -49,7 +49,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.pf = select_pf_by_ver(LSQVER_ID25),
|
||||
.offset = 500,
|
||||
.data_sz = 10,
|
||||
.data = "0123456789",
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include "lsquic_hq.h"
|
||||
#include "lsquic_data_in_if.h"
|
||||
|
||||
static const struct parse_funcs *g_pf = select_pf_by_ver(LSQVER_ID24);
|
||||
static const struct parse_funcs *g_pf = select_pf_by_ver(LSQVER_ID25);
|
||||
|
||||
struct test_ctl_settings
|
||||
{
|
||||
|
@ -297,7 +297,7 @@ init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
|||
memset(tobjs, 0, sizeof(*tobjs));
|
||||
LSCONN_INITIALIZE(&tobjs->lconn);
|
||||
tobjs->lconn.cn_pf = g_pf;
|
||||
tobjs->lconn.cn_version = LSQVER_ID24;
|
||||
tobjs->lconn.cn_version = LSQVER_ID25;
|
||||
tobjs->lconn.cn_esf_c = &lsquic_enc_session_common_ietf_v1;
|
||||
network_path.np_pack_size = packet_sz;
|
||||
tobjs->lconn.cn_if = &our_conn_if;
|
||||
|
|
|
@ -158,8 +158,8 @@ init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
|||
int s;
|
||||
memset(tobjs, 0, sizeof(*tobjs));
|
||||
LSCONN_INITIALIZE(&tobjs->lconn);
|
||||
tobjs->lconn.cn_pf = select_pf_by_ver(LSQVER_ID24);
|
||||
tobjs->lconn.cn_version = LSQVER_ID24;
|
||||
tobjs->lconn.cn_pf = select_pf_by_ver(LSQVER_ID25);
|
||||
tobjs->lconn.cn_version = LSQVER_ID25;
|
||||
tobjs->lconn.cn_esf_c = &lsquic_enc_session_common_ietf_v1;
|
||||
network_path.np_pack_size = IQUIC_MAX_IPv4_PACKET_SZ;
|
||||
tobjs->lconn.cn_if = &our_conn_if;
|
||||
|
|
|
@ -325,7 +325,7 @@ init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
|||
LSCONN_INITIALIZE(&tobjs->lconn);
|
||||
tobjs->lconn.cn_pf = pf ? pf : g_pf;
|
||||
tobjs->lconn.cn_version = tobjs->lconn.cn_pf == &lsquic_parse_funcs_ietf_v1 ?
|
||||
LSQVER_ID24 : LSQVER_043;
|
||||
LSQVER_ID25 : LSQVER_043;
|
||||
tobjs->lconn.cn_esf_c = &lsquic_enc_session_common_gquic_1;
|
||||
network_path.np_pack_size = 1370;
|
||||
tobjs->lconn.cn_if = &our_conn_if;
|
||||
|
@ -2243,7 +2243,7 @@ test_changing_pack_size (void)
|
|||
enum lsquic_version versions_to_test[3] =
|
||||
{
|
||||
LSQVER_046,
|
||||
LSQVER_ID24,
|
||||
LSQVER_ID25,
|
||||
};
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
|
@ -3173,7 +3173,7 @@ main (int argc, char **argv)
|
|||
|
||||
/* Redo some tests using crypto streams and frames */
|
||||
g_use_crypto_ctor = 1;
|
||||
g_pf = select_pf_by_ver(LSQVER_ID24);
|
||||
g_pf = select_pf_by_ver(LSQVER_ID25);
|
||||
main_test_packetization();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -279,7 +279,7 @@ static const struct test tests[] = {
|
|||
*/
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.pf = select_pf_by_ver(LSQVER_ID25),
|
||||
.fin = { 0, 1, },
|
||||
.offset = 0x0807060504030201UL,
|
||||
.stream_id = 0x210,
|
||||
|
@ -299,7 +299,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.pf = select_pf_by_ver(LSQVER_ID25),
|
||||
.fin = { 0, 0, },
|
||||
.offset = 0,
|
||||
.stream_id = 0x210,
|
||||
|
@ -318,7 +318,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.pf = select_pf_by_ver(LSQVER_ID25),
|
||||
.fin = { 0, 0, },
|
||||
.offset = 0,
|
||||
.stream_id = 0x21,
|
||||
|
@ -336,7 +336,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.pf = select_pf_by_ver(LSQVER_ID25),
|
||||
.fin = { 0, 0, },
|
||||
.offset = 0x0807060504030201UL,
|
||||
.stream_id = 0x210,
|
||||
|
@ -356,7 +356,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.pf = select_pf_by_ver(LSQVER_ID25),
|
||||
.fin = { 1, 0, },
|
||||
.offset = 0x0807060504030201UL,
|
||||
.stream_id = 0x210,
|
||||
|
@ -374,7 +374,7 @@ static const struct test tests[] = {
|
|||
},
|
||||
|
||||
{ .lineno = __LINE__,
|
||||
.pf = select_pf_by_ver(LSQVER_ID24),
|
||||
.pf = select_pf_by_ver(LSQVER_ID25),
|
||||
.fin = { 1, 0, },
|
||||
.offset = 0x0807060504030201UL,
|
||||
.stream_id = 0x210,
|
||||
|
|
|
@ -243,7 +243,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Balls to the wall: every possible bit is set",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 1<<0,
|
||||
0x41, 0x23, /* Stream ID */
|
||||
|
@ -262,7 +262,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Balls to the wall #2: every possible bit is set except FIN",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -281,7 +281,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Data length is zero",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 0<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -299,7 +299,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Sanity check: what happens when data length is zero #1",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -318,7 +318,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Sanity check: what happens when data length is zero #2",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -337,7 +337,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Sanity check: what happens when data length is zero #3",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 0<<2 | 1<<1 | 0<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -355,7 +355,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Sanity check: what happens when data length is zero #3",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 1<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -374,7 +374,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Check data bounds #1",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 1<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
@ -393,7 +393,7 @@ static const struct test tests[] = {
|
|||
|
||||
{ "Check data bounds #2",
|
||||
__LINE__,
|
||||
select_pf_by_ver(LSQVER_ID24),
|
||||
select_pf_by_ver(LSQVER_ID25),
|
||||
/* TYPE OFF DLEN FIN */
|
||||
{ 0x10 | 1<<2 | 1<<1 | 1<<0,
|
||||
0x81, 0x23, 0x00, 0xE4, /* Stream ID */
|
||||
|
|
|
@ -44,9 +44,8 @@ static const struct trapa_test tests[] =
|
|||
.params = {
|
||||
TP_DEFAULT_VALUES,
|
||||
},
|
||||
.enc_len = 2,
|
||||
.enc_len = 0,
|
||||
.encoded =
|
||||
/* Overall length */ "\x00\x00"
|
||||
/* Trailer to make the end easily visible in gdb: */
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
},
|
||||
|
@ -69,15 +68,14 @@ static const struct trapa_test tests[] =
|
|||
.tp_active_connection_id_limit = 7,
|
||||
},
|
||||
.is_server = 0,
|
||||
.enc_len = 39,
|
||||
.enc_len = 25,
|
||||
.encoded =
|
||||
/* Overall length */ "\x00\x25"
|
||||
/* Idle timeout */ "\x00\x01\x00\x02\x67\x10"
|
||||
/* Packet size */ "\x00\x03\x00\x01\x00"
|
||||
/* Max data */ "\x00\x04\x00\x04\x80\x00\xAA\xBB"
|
||||
/* Bidi local */ "\x00\x05\x00\x04\x92\x34\x88\x77"
|
||||
/* Ack delay exp */ "\x00\x0A\x00\x01\x00"
|
||||
/* Active CID limit */ "\x00\x0E\x00\x01\x07"
|
||||
/* Idle timeout */ "\x01\x02\x67\x10"
|
||||
/* Packet size */ "\x03\x01\x00"
|
||||
/* Max data */ "\x04\x04\x80\x00\xAA\xBB"
|
||||
/* Bidi local */ "\x05\x04\x92\x34\x88\x77"
|
||||
/* Ack delay exp */ "\x0A\x01\x00"
|
||||
/* Active CID limit */ "\x0E\x01\x07"
|
||||
/* Trailer to make the end easily visible in gdb: */
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
},
|
||||
|
@ -109,13 +107,12 @@ static const struct trapa_test tests[] =
|
|||
},
|
||||
.is_server = 1,
|
||||
.addl_set = 1 << TPI_DISABLE_ACTIVE_MIGRATION,
|
||||
.enc_len = 32,
|
||||
.enc_len = 22,
|
||||
.encoded =
|
||||
/* Overall length */ "\x00\x1E"
|
||||
/* Packet size */ "\x00\x03\x00\x02\x43\x33"
|
||||
/* Max data */ "\x00\x04\x00\x04\x80\x12\x34\x56"
|
||||
/* Bidi local */ "\x00\x05\x00\x08\xC0\x00\x00\x00\xAB\xCD\xEF\x88"
|
||||
/* Migration */ "\x00\x0C\x00\x00"
|
||||
/* Packet size */ "\x03\x02\x43\x33"
|
||||
/* Max data */ "\x04\x04\x80\x12\x34\x56"
|
||||
/* Bidi local */ "\x05\x08\xC0\x00\x00\x00\xAB\xCD\xEF\x88"
|
||||
/* Migration */ "\x0C\x00"
|
||||
/* Trailer to make the end easily visible in gdb: */
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
},
|
||||
|
@ -139,11 +136,11 @@ static const struct trapa_test tests[] =
|
|||
},
|
||||
.is_server = 1,
|
||||
.addl_set = 1 << TPI_PREFERRED_ADDRESS,
|
||||
.enc_len = 0x3E + 2,
|
||||
.enc_len = 0x3A,
|
||||
.dec_len = 0x3A,
|
||||
.encoded =
|
||||
/* Overall length */ "\x00\x3E"
|
||||
/* Preferred Address */"\x00\x0D"
|
||||
"\x00\x34"
|
||||
/* Preferred Address */"\x0D"
|
||||
"\x34"
|
||||
"\x01\x02\x03\x04"
|
||||
"\x12\x34"
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
|
||||
|
@ -151,7 +148,7 @@ static const struct trapa_test tests[] =
|
|||
"\x0B" /* CID len */
|
||||
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A"
|
||||
"\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
|
||||
/* Packet size */ "\x00\x03\x00\x02\x43\x33"
|
||||
/* Packet size */ "\x03\x02\x43\x33"
|
||||
/* Trailer to make the end easily visible in gdb: */
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
},
|
||||
|
@ -196,7 +193,7 @@ run_test (const struct trapa_test *test)
|
|||
if (test->flags & TEST_ENCODE)
|
||||
{
|
||||
s = lsquic_tp_encode(&source_params, test->is_server, buf, sizeof(buf));
|
||||
assert(s > 0);
|
||||
assert(s >= 0);
|
||||
assert((size_t) s == test->enc_len);
|
||||
assert(0 == memcmp(test->encoded, buf, s));
|
||||
}
|
||||
|
@ -206,12 +203,12 @@ run_test (const struct trapa_test *test)
|
|||
if (test->dec_len)
|
||||
dec_len = test->dec_len;
|
||||
else
|
||||
dec_len = sizeof(buf);
|
||||
dec_len = test->enc_len;
|
||||
s = lsquic_tp_decode(test->encoded, dec_len,
|
||||
test->is_server, &decoded_params);
|
||||
if (!test->expect_decode_err)
|
||||
{
|
||||
assert(s > 0);
|
||||
assert(s >= 0);
|
||||
assert((size_t) s == test->enc_len);
|
||||
/* The decoder initializes all default values, so set the flag
|
||||
* accordingly:
|
||||
|
|
Loading…
Reference in a new issue