mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.10.5
- [BUGFIX] BBR: call cci_sent() with correct arguments and at correct time. - Refactor transport parameters module. - Minor code cleanup.
This commit is contained in:
parent
e68b045258
commit
1bdb91d191
12 changed files with 460 additions and 458 deletions
|
@ -1,3 +1,10 @@
|
|||
2020-02-13
|
||||
- 2.10.5
|
||||
- [BUGFIX] BBR: call cci_sent() with correct arguments and at correct
|
||||
time.
|
||||
- Refactor transport parameters module.
|
||||
- Minor code cleanup.
|
||||
|
||||
2020-02-11
|
||||
- 2.10.4
|
||||
- [BUGFIX] Send HANDSHAKE_DONE only after Finished is received.
|
||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
|
||||
#define LSQUIC_MAJOR_VERSION 2
|
||||
#define LSQUIC_MINOR_VERSION 10
|
||||
#define LSQUIC_PATCH_VERSION 4
|
||||
#define LSQUIC_PATCH_VERSION 5
|
||||
|
||||
/**
|
||||
* Engine flags:
|
||||
|
@ -757,7 +757,6 @@ struct lsquic_engine_settings {
|
|||
* 0: Do not use loss bits
|
||||
* 1: Allow loss bits
|
||||
* 2: Allow and send loss bits
|
||||
* -1: Allow and send loss bits, sending old-style boolean loss_bits TP
|
||||
*
|
||||
* Default value is @ref LSQUIC_DF_QL_BITS
|
||||
*/
|
||||
|
|
|
@ -436,15 +436,14 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
{
|
||||
const struct lsquic_conn *const lconn = enc_sess->esi_conn;
|
||||
|
||||
params.tp_flags |= TRAPA_SERVER|TRAPA_RESET_TOKEN;
|
||||
|
||||
params.tp_set |= 1 << TPI_STATELESS_RESET_TOKEN;
|
||||
lsquic_tg_generate_sreset(enc_sess->esi_enpub->enp_tokgen,
|
||||
CN_SCID(lconn), params.tp_stateless_reset_token);
|
||||
|
||||
if (enc_sess->esi_flags & ESI_ODCID)
|
||||
{
|
||||
params.tp_original_cid = enc_sess->esi_odcid;
|
||||
params.tp_flags |= TRAPA_ORIGINAL_CID;
|
||||
params.tp_set |= 1 << TPI_ORIGINAL_CONNECTION_ID;
|
||||
}
|
||||
#if LSQUIC_PREFERRED_ADDR
|
||||
char addr_buf[INET6_ADDRSTRLEN + 6 /* port */ + 1];
|
||||
|
@ -459,7 +458,7 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
addr_buf[colon - s] = '\0';
|
||||
inet_pton(AF_INET, addr_buf, params.tp_preferred_address.ipv4_addr);
|
||||
params.tp_preferred_address.ipv4_port = atoi(colon + 1);
|
||||
params.tp_flags |= TRAPA_PREFADDR_IPv4;
|
||||
params.tp_set |= 1 << TPI_PREFERRED_ADDRESS;
|
||||
}
|
||||
s = getenv("LSQUIC_PREFERRED_ADDR6");
|
||||
if (s && strlen(s) < sizeof(addr_buf) && (colon = strrchr(s, ':')))
|
||||
|
@ -469,10 +468,10 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
inet_pton(AF_INET6, addr_buf,
|
||||
params.tp_preferred_address.ipv6_addr);
|
||||
params.tp_preferred_address.ipv6_port = atoi(colon + 1);
|
||||
params.tp_flags |= TRAPA_PREFADDR_IPv6;
|
||||
params.tp_set |= 1 << TPI_PREFERRED_ADDRESS;
|
||||
}
|
||||
conn = enc_sess->esi_conn;
|
||||
if ((params.tp_flags & (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6))
|
||||
if ((params.tp_set & (1 << TPI_PREFERRED_ADDRESS))
|
||||
&& (1 << conn->cn_n_cces) - 1 != conn->cn_cces_mask)
|
||||
{
|
||||
seqno = 0;
|
||||
|
@ -506,7 +505,7 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
else
|
||||
{
|
||||
cant_use_prefaddr:
|
||||
params.tp_flags &= ~(TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6);
|
||||
params.tp_set &= ~(1 << TPI_PREFERRED_ADDRESS);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -515,7 +514,7 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
{
|
||||
const char *s = getenv("LSQUIC_TEST_QUANTUM_READINESS");
|
||||
if (s && atoi(s))
|
||||
params.tp_flags |= TRAPA_QUANTUM_READY;
|
||||
params.tp_set |= 1 << TPI_QUANTUM_READINESS;
|
||||
}
|
||||
#endif
|
||||
params.tp_init_max_data = settings->es_init_max_data;
|
||||
|
@ -535,23 +534,33 @@ gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
|
|||
params.tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY;
|
||||
params.tp_max_packet_size = 1370 /* XXX: based on socket */;
|
||||
params.tp_active_connection_id_limit = MAX_IETF_CONN_DCIDS;
|
||||
params.tp_set |= (1 << TPI_INIT_MAX_DATA)
|
||||
| (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL)
|
||||
| (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE)
|
||||
| (1 << TPI_INIT_MAX_STREAM_DATA_UNI)
|
||||
| (1 << TPI_INIT_MAX_STREAMS_UNI)
|
||||
| (1 << TPI_INIT_MAX_STREAMS_BIDI)
|
||||
| (1 << TPI_ACK_DELAY_EXPONENT)
|
||||
| (1 << TPI_MAX_IDLE_TIMEOUT)
|
||||
| (1 << TPI_MAX_ACK_DELAY)
|
||||
| (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_flags & (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6));
|
||||
- !!(params.tp_set & (1 << TPI_PREFERRED_ADDRESS));
|
||||
}
|
||||
if (!settings->es_allow_migration)
|
||||
params.tp_disable_active_migration = 1;
|
||||
if (settings->es_ql_bits == -1)
|
||||
params.tp_flags |= TRAPA_QL_BITS_OLD;
|
||||
else if (settings->es_ql_bits)
|
||||
params.tp_set |= 1 << TPI_DISABLE_ACTIVE_MIGRATION;
|
||||
if (settings->es_ql_bits)
|
||||
{
|
||||
params.tp_loss_bits = settings->es_ql_bits - 1;
|
||||
params.tp_flags |= TRAPA_QL_BITS;
|
||||
params.tp_set |= 1 << TPI_LOSS_BITS;
|
||||
}
|
||||
|
||||
len = lsquic_tp_encode(¶ms, buf, bufsz);
|
||||
len = 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
|
||||
|
@ -1458,7 +1467,7 @@ get_peer_transport_params (struct enc_sess_iquic *enc_sess)
|
|||
|
||||
if ((enc_sess->esi_flags & (ESI_ODCID|ESI_SERVER)) == ESI_ODCID)
|
||||
{
|
||||
if (!(trans_params->tp_flags & TRAPA_ORIGINAL_CID))
|
||||
if (!(trans_params->tp_set & (1 << TPI_ORIGINAL_CONNECTION_ID)))
|
||||
{
|
||||
LSQ_DEBUG("server did not produce original DCID (ODCID)");
|
||||
return -1;
|
||||
|
@ -1480,15 +1489,11 @@ get_peer_transport_params (struct enc_sess_iquic *enc_sess)
|
|||
}
|
||||
}
|
||||
|
||||
if ((trans_params->tp_flags & TRAPA_QL_BITS)
|
||||
if ((trans_params->tp_set & (1 << TPI_LOSS_BITS))
|
||||
&& enc_sess->esi_enpub->enp_settings.es_ql_bits)
|
||||
{
|
||||
unsigned our_loss_bits;
|
||||
if (enc_sess->esi_enpub->enp_settings.es_ql_bits == -1)
|
||||
our_loss_bits = 1;
|
||||
else
|
||||
our_loss_bits = enc_sess->esi_enpub->enp_settings.es_ql_bits - 1;
|
||||
|
||||
const unsigned our_loss_bits
|
||||
= enc_sess->esi_enpub->enp_settings.es_ql_bits - 1;
|
||||
switch ((our_loss_bits << 1) | trans_params->tp_loss_bits)
|
||||
{
|
||||
case (0 << 1) | 0:
|
||||
|
|
|
@ -403,7 +403,7 @@ lsquic_engine_check_settings (const struct lsquic_engine_settings *settings,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!(settings->es_ql_bits >= -1 && settings->es_ql_bits <= 2))
|
||||
if (!(settings->es_ql_bits >= 0 && settings->es_ql_bits <= 2))
|
||||
{
|
||||
if (err_buf)
|
||||
snprintf(err_buf, err_buf_sz, "Invalid QL bits value %d ",
|
||||
|
|
|
@ -2592,10 +2592,10 @@ begin_migra_or_retire_cid (struct id24_full_conn *conn,
|
|||
struct sockaddr_in6 v6;
|
||||
} sockaddr;
|
||||
|
||||
if (params->tp_disable_active_migration
|
||||
if ((params->tp_set & (1 << TPI_DISABLE_ACTIVE_MIGRATION))
|
||||
|| !conn->ifc_settings->es_allow_migration)
|
||||
{
|
||||
if (params->tp_disable_active_migration)
|
||||
if (params->tp_set & (1 << TPI_DISABLE_ACTIVE_MIGRATION))
|
||||
LSQ_DEBUG("TP disables migration: retire PreferredAddress CID");
|
||||
else
|
||||
LSQ_DEBUG("Migration not allowed: retire PreferredAddress CID");
|
||||
|
@ -2604,8 +2604,8 @@ begin_migra_or_retire_cid (struct id24_full_conn *conn,
|
|||
}
|
||||
|
||||
is_ipv6 = NP_IS_IPv6(CUR_NPATH(conn));
|
||||
if ((is_ipv6 && !(params->tp_flags & TRAPA_PREFADDR_IPv6))
|
||||
|| (!is_ipv6 && !(params->tp_flags & TRAPA_PREFADDR_IPv4)))
|
||||
if ((is_ipv6 && !lsquic_tp_has_pref_ipv6(params))
|
||||
|| (!is_ipv6 && !lsquic_tp_has_pref_ipv4(params)))
|
||||
{
|
||||
/* XXX This is a limitation in the client code outside of the library.
|
||||
* To support cross-IP-version migration, we need to add some callbacks
|
||||
|
@ -2683,7 +2683,7 @@ maybe_start_migration (struct id24_full_conn *conn)
|
|||
|
||||
params = lconn->cn_esf.i->esfi_get_peer_transport_params(
|
||||
lconn->cn_enc_session);
|
||||
if (params->tp_flags & (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6))
|
||||
if (params->tp_set & (1 << TPI_PREFERRED_ADDRESS))
|
||||
{
|
||||
if (0 != begin_migra_or_retire_cid(conn, params))
|
||||
ABORT_QUIETLY(0, TEC_INTERNAL_ERROR, "error initiating migration");
|
||||
|
@ -2721,9 +2721,8 @@ handshake_ok (struct lsquic_conn *lconn)
|
|||
LSQ_DEBUG("peer transport parameters: %s",
|
||||
(lsquic_tp_to_str(params, buf, sizeof(buf)), buf));
|
||||
|
||||
if ((params->tp_flags & TRAPA_QL_BITS)
|
||||
&& (conn->ifc_settings->es_ql_bits == 2
|
||||
|| conn->ifc_settings->es_ql_bits == -1))
|
||||
if ((params->tp_set & (1 << TPI_LOSS_BITS))
|
||||
&& conn->ifc_settings->es_ql_bits == 2)
|
||||
{
|
||||
LSQ_DEBUG("turn on QL loss bits");
|
||||
lsquic_send_ctl_do_ql_bits(&conn->ifc_send_ctl);
|
||||
|
@ -2797,7 +2796,7 @@ handshake_ok (struct lsquic_conn *lconn)
|
|||
memset(dce, 0, sizeof(*dce));
|
||||
dce->de_cid = *CUR_DCID(conn);
|
||||
dce->de_seqno = 0;
|
||||
if (params->tp_flags & TRAPA_RESET_TOKEN)
|
||||
if (params->tp_set & (1 << TPI_STATELESS_RESET_TOKEN))
|
||||
{
|
||||
memcpy(dce->de_srst, params->tp_stateless_reset_token,
|
||||
sizeof(dce->de_srst));
|
||||
|
@ -4795,7 +4794,7 @@ must_reserve_one_dce_slot (struct id24_full_conn *conn)
|
|||
params = lconn->cn_esf.i->esfi_get_peer_transport_params(
|
||||
lconn->cn_enc_session);
|
||||
if (params) /* Just in case */
|
||||
return !!(params->tp_flags & (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6));
|
||||
return !!(params->tp_set & (1 << TPI_PREFERRED_ADDRESS));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2765,10 +2765,10 @@ begin_migra_or_retire_cid (struct ietf_full_conn *conn,
|
|||
struct sockaddr_in6 v6;
|
||||
} sockaddr;
|
||||
|
||||
if (params->tp_disable_active_migration
|
||||
if ((params->tp_set & (1 << TPI_DISABLE_ACTIVE_MIGRATION))
|
||||
|| !conn->ifc_settings->es_allow_migration)
|
||||
{
|
||||
if (params->tp_disable_active_migration)
|
||||
if (params->tp_set & (1 << TPI_DISABLE_ACTIVE_MIGRATION))
|
||||
LSQ_DEBUG("TP disables migration: retire PreferredAddress CID");
|
||||
else
|
||||
LSQ_DEBUG("Migration not allowed: retire PreferredAddress CID");
|
||||
|
@ -2777,8 +2777,8 @@ begin_migra_or_retire_cid (struct ietf_full_conn *conn,
|
|||
}
|
||||
|
||||
is_ipv6 = NP_IS_IPv6(CUR_NPATH(conn));
|
||||
if ((is_ipv6 && !(params->tp_flags & TRAPA_PREFADDR_IPv6))
|
||||
|| (!is_ipv6 && !(params->tp_flags & TRAPA_PREFADDR_IPv4)))
|
||||
if ((is_ipv6 && !lsquic_tp_has_pref_ipv6(params))
|
||||
|| (!is_ipv6 && !lsquic_tp_has_pref_ipv4(params)))
|
||||
{
|
||||
/* XXX This is a limitation in the client code outside of the library.
|
||||
* To support cross-IP-version migration, we need to add some callbacks
|
||||
|
@ -2856,7 +2856,7 @@ maybe_start_migration (struct ietf_full_conn *conn)
|
|||
|
||||
params = lconn->cn_esf.i->esfi_get_peer_transport_params(
|
||||
lconn->cn_enc_session);
|
||||
if (params->tp_flags & (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6))
|
||||
if (params->tp_set & (1 << TPI_PREFERRED_ADDRESS))
|
||||
{
|
||||
if (0 != begin_migra_or_retire_cid(conn, params))
|
||||
ABORT_QUIETLY(0, TEC_INTERNAL_ERROR, "error initiating migration");
|
||||
|
@ -2894,9 +2894,8 @@ handshake_ok (struct lsquic_conn *lconn)
|
|||
LSQ_DEBUG("peer transport parameters: %s",
|
||||
(lsquic_tp_to_str(params, buf, sizeof(buf)), buf));
|
||||
|
||||
if ((params->tp_flags & TRAPA_QL_BITS)
|
||||
&& (conn->ifc_settings->es_ql_bits == 2
|
||||
|| conn->ifc_settings->es_ql_bits == -1))
|
||||
if ((params->tp_set & (1 << TPI_LOSS_BITS))
|
||||
&& conn->ifc_settings->es_ql_bits == 2)
|
||||
{
|
||||
LSQ_DEBUG("turn on QL loss bits");
|
||||
lsquic_send_ctl_do_ql_bits(&conn->ifc_send_ctl);
|
||||
|
@ -3005,7 +3004,7 @@ handshake_ok (struct lsquic_conn *lconn)
|
|||
memset(dce, 0, sizeof(*dce));
|
||||
dce->de_cid = *CUR_DCID(conn);
|
||||
dce->de_seqno = 0;
|
||||
if (params->tp_flags & TRAPA_RESET_TOKEN)
|
||||
if (params->tp_set & (1 << TPI_STATELESS_RESET_TOKEN))
|
||||
{
|
||||
memcpy(dce->de_srst, params->tp_stateless_reset_token,
|
||||
sizeof(dce->de_srst));
|
||||
|
|
|
@ -887,9 +887,10 @@ gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
|
|||
*type |= bits;
|
||||
|
||||
CHECKOUT(largest_acked_len);
|
||||
tmp_packno = maxno;
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
tmp_packno = bswap_64(maxno);
|
||||
#else
|
||||
tmp_packno = maxno;
|
||||
#endif
|
||||
memcpy(p, (unsigned char *) &tmp_packno + 8 - largest_acked_len,
|
||||
largest_acked_len);
|
||||
|
|
|
@ -655,6 +655,9 @@ lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *ctl,
|
|||
packet_out->po_packno, lsquic_frame_types_to_str(frames,
|
||||
sizeof(frames), packet_out->po_frame_types));
|
||||
lsquic_senhist_add(&ctl->sc_senhist, packet_out->po_packno);
|
||||
if (ctl->sc_ci->cci_sent)
|
||||
ctl->sc_ci->cci_sent(CGP(ctl), packet_out, ctl->sc_bytes_unacked_all,
|
||||
ctl->sc_flags & SC_APP_LIMITED);
|
||||
send_ctl_unacked_append(ctl, packet_out);
|
||||
if (packet_out->po_frame_types & ctl->sc_retx_frames)
|
||||
{
|
||||
|
@ -670,9 +673,6 @@ lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *ctl,
|
|||
#if LSQUIC_SEND_STATS
|
||||
++ctl->sc_stats.n_total_sent;
|
||||
#endif
|
||||
if (ctl->sc_ci->cci_sent)
|
||||
ctl->sc_ci->cci_sent(CGP(ctl), packet_out, ctl->sc_n_in_flight_all,
|
||||
ctl->sc_flags & SC_APP_LIMITED);
|
||||
lsquic_send_ctl_sanity_check(ctl);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3407,10 +3407,10 @@ lsquic_stream_writef (lsquic_stream_t *stream, struct lsquic_reader *reader)
|
|||
static ssize_t
|
||||
stream_write_buf (struct lsquic_stream *stream, const void *buf, size_t sz)
|
||||
{
|
||||
struct iovec iov = { (void *) buf, sz, };
|
||||
const struct iovec iov[1] = {{ (void *) buf, sz, }};
|
||||
struct inner_reader_iovec iro = {
|
||||
.iov = &iov,
|
||||
.end = &iov + 1,
|
||||
.iov = iov,
|
||||
.end = iov + 1,
|
||||
.cur_iovec_off = 0,
|
||||
};
|
||||
struct lsquic_reader reader = {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
@ -26,7 +27,84 @@
|
|||
#include "lsquic_logger.h"
|
||||
|
||||
|
||||
static const uint64_t def_vals[MAX_TPI + 1] =
|
||||
static enum transport_param_id
|
||||
tpi_val_2_enum (uint64_t tpi_val)
|
||||
{
|
||||
switch (tpi_val)
|
||||
{
|
||||
case 0: return TPI_ORIGINAL_CONNECTION_ID;
|
||||
case 1: return TPI_MAX_IDLE_TIMEOUT;
|
||||
case 2: return TPI_STATELESS_RESET_TOKEN;
|
||||
case 3: return TPI_MAX_PACKET_SIZE;
|
||||
case 4: return TPI_INIT_MAX_DATA;
|
||||
case 5: return TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL;
|
||||
case 6: return TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE;
|
||||
case 7: return TPI_INIT_MAX_STREAM_DATA_UNI;
|
||||
case 8: return TPI_INIT_MAX_STREAMS_BIDI;
|
||||
case 9: return TPI_INIT_MAX_STREAMS_UNI;
|
||||
case 10: return TPI_ACK_DELAY_EXPONENT;
|
||||
case 11: return TPI_MAX_ACK_DELAY;
|
||||
case 12: return TPI_DISABLE_ACTIVE_MIGRATION;
|
||||
case 13: return TPI_PREFERRED_ADDRESS;
|
||||
case 14: return TPI_ACTIVE_CONNECTION_ID_LIMIT;
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
case 0xC37: return TPI_QUANTUM_READINESS;
|
||||
#endif
|
||||
case 0x1057: return TPI_LOSS_BITS;
|
||||
default: return INT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const unsigned short enum_2_tpi_val[LAST_TPI + 1] =
|
||||
{
|
||||
[TPI_ORIGINAL_CONNECTION_ID] = 0x0,
|
||||
[TPI_MAX_IDLE_TIMEOUT] = 0x1,
|
||||
[TPI_STATELESS_RESET_TOKEN] = 0x2,
|
||||
[TPI_MAX_PACKET_SIZE] = 0x3,
|
||||
[TPI_INIT_MAX_DATA] = 0x4,
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = 0x5,
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = 0x6,
|
||||
[TPI_INIT_MAX_STREAM_DATA_UNI] = 0x7,
|
||||
[TPI_INIT_MAX_STREAMS_BIDI] = 0x8,
|
||||
[TPI_INIT_MAX_STREAMS_UNI] = 0x9,
|
||||
[TPI_ACK_DELAY_EXPONENT] = 0xA,
|
||||
[TPI_MAX_ACK_DELAY] = 0xB,
|
||||
[TPI_DISABLE_ACTIVE_MIGRATION] = 0xC,
|
||||
[TPI_PREFERRED_ADDRESS] = 0xD,
|
||||
[TPI_ACTIVE_CONNECTION_ID_LIMIT] = 0xE,
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
[TPI_QUANTUM_READINESS] = 0xC37,
|
||||
#endif
|
||||
[TPI_LOSS_BITS] = 0x1057,
|
||||
};
|
||||
|
||||
|
||||
static const char * const tpi2str[LAST_TPI + 1] =
|
||||
{
|
||||
[TPI_ORIGINAL_CONNECTION_ID] = "original_connection_id",
|
||||
[TPI_MAX_IDLE_TIMEOUT] = "max_idle_timeout",
|
||||
[TPI_STATELESS_RESET_TOKEN] = "stateless_reset_token",
|
||||
[TPI_MAX_PACKET_SIZE] = "max_packet_size",
|
||||
[TPI_INIT_MAX_DATA] = "init_max_data",
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = "init_max_stream_data_bidi_local",
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = "init_max_stream_data_bidi_remote",
|
||||
[TPI_INIT_MAX_STREAM_DATA_UNI] = "init_max_stream_data_uni",
|
||||
[TPI_INIT_MAX_STREAMS_BIDI] = "init_max_streams_bidi",
|
||||
[TPI_INIT_MAX_STREAMS_UNI] = "init_max_streams_uni",
|
||||
[TPI_ACK_DELAY_EXPONENT] = "ack_delay_exponent",
|
||||
[TPI_MAX_ACK_DELAY] = "max_ack_delay",
|
||||
[TPI_DISABLE_ACTIVE_MIGRATION] = "disable_active_migration",
|
||||
[TPI_PREFERRED_ADDRESS] = "preferred_address",
|
||||
[TPI_ACTIVE_CONNECTION_ID_LIMIT] = "active_connection_id_limit",
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
[TPI_QUANTUM_READINESS] = "quantum_readiness",
|
||||
#endif
|
||||
[TPI_LOSS_BITS] = "loss_bits",
|
||||
};
|
||||
|
||||
|
||||
static const uint64_t def_vals[MAX_NUM_WITH_DEF_TPI + 1] =
|
||||
{
|
||||
[TPI_MAX_PACKET_SIZE] = TP_DEF_MAX_PACKET_SIZE,
|
||||
[TPI_ACK_DELAY_EXPONENT] = TP_DEF_ACK_DELAY_EXP,
|
||||
|
@ -42,7 +120,7 @@ static const uint64_t def_vals[MAX_TPI + 1] =
|
|||
};
|
||||
|
||||
|
||||
static const uint64_t max_vals[MAX_TPI + 1] =
|
||||
static const uint64_t max_vals[MAX_NUMERIC_TPI + 1] =
|
||||
{
|
||||
[TPI_MAX_PACKET_SIZE] = VINT_MAX_VALUE,
|
||||
[TPI_ACK_DELAY_EXPONENT] = VINT_MAX_VALUE,
|
||||
|
@ -55,27 +133,7 @@ static const uint64_t max_vals[MAX_TPI + 1] =
|
|||
[TPI_MAX_IDLE_TIMEOUT] = VINT_MAX_VALUE,
|
||||
[TPI_MAX_ACK_DELAY] = TP_MAX_MAX_ACK_DELAY,
|
||||
[TPI_ACTIVE_CONNECTION_ID_LIMIT] = VINT_MAX_VALUE,
|
||||
};
|
||||
|
||||
|
||||
#define TP_OFF(name_) ((uint64_t *) &((struct transport_params *) 0 \
|
||||
)->tp_numerics_u.s.name_ - (uint64_t *) &((struct transport_params *) \
|
||||
0)->tp_numerics_u.s)
|
||||
|
||||
/* Map enum transport_params to index of tp_numerics_u.a; for numeric values only */
|
||||
static const unsigned tpi2idx[MAX_TPI + 1] =
|
||||
{
|
||||
[TPI_MAX_PACKET_SIZE] = TP_OFF(max_packet_size),
|
||||
[TPI_ACK_DELAY_EXPONENT] = TP_OFF(ack_delay_exponent),
|
||||
[TPI_INIT_MAX_STREAMS_UNI] = TP_OFF(init_max_streams_uni),
|
||||
[TPI_INIT_MAX_STREAMS_BIDI] = TP_OFF(init_max_streams_bidi),
|
||||
[TPI_INIT_MAX_DATA] = TP_OFF(init_max_data),
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL] = TP_OFF(init_max_stream_data_bidi_local),
|
||||
[TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE] = TP_OFF(init_max_stream_data_bidi_remote),
|
||||
[TPI_INIT_MAX_STREAM_DATA_UNI] = TP_OFF(init_max_stream_data_uni),
|
||||
[TPI_MAX_IDLE_TIMEOUT] = TP_OFF(max_idle_timeout),
|
||||
[TPI_MAX_ACK_DELAY] = TP_OFF(max_ack_delay),
|
||||
[TPI_ACTIVE_CONNECTION_ID_LIMIT] = TP_OFF(active_connection_id_limit),
|
||||
[TPI_LOSS_BITS] = 1,
|
||||
};
|
||||
|
||||
|
||||
|
@ -93,54 +151,78 @@ preferred_address_size (const struct transport_params *params)
|
|||
|
||||
|
||||
int
|
||||
lsquic_tp_encode (const struct transport_params *params,
|
||||
lsquic_tp_has_pref_ipv4 (const struct transport_params *params)
|
||||
{
|
||||
return (params->tp_set & (1 << TPI_PREFERRED_ADDRESS))
|
||||
&& params->tp_preferred_address.ipv4_port
|
||||
&& !lsquic_is_zero(params->tp_preferred_address.ipv4_addr,
|
||||
sizeof(params->tp_preferred_address.ipv4_addr));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lsquic_tp_has_pref_ipv6 (const struct transport_params *params)
|
||||
{
|
||||
return (params->tp_set & (1 << TPI_PREFERRED_ADDRESS))
|
||||
&& params->tp_preferred_address.ipv6_port
|
||||
&& !lsquic_is_zero(params->tp_preferred_address.ipv6_addr,
|
||||
sizeof(params->tp_preferred_address.ipv6_addr));
|
||||
}
|
||||
|
||||
|
||||
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 = 2;
|
||||
uint16_t u16;
|
||||
enum transport_param_id tpi;
|
||||
unsigned bits[MAX_TPI + 1];
|
||||
unsigned set;
|
||||
unsigned bits[MAX_NUMERIC_TPI + 1];
|
||||
|
||||
if (params->tp_flags & TRAPA_SERVER)
|
||||
set = params->tp_set; /* Will turn bits off for default values */
|
||||
|
||||
if (is_server)
|
||||
{
|
||||
if (params->tp_flags & TRAPA_ORIGINAL_CID)
|
||||
if (set & (1 << TPI_ORIGINAL_CONNECTION_ID))
|
||||
need += 4 + params->tp_original_cid.len;
|
||||
if (params->tp_flags & TRAPA_RESET_TOKEN)
|
||||
if (set & (1 << TPI_STATELESS_RESET_TOKEN))
|
||||
need += 4 + sizeof(params->tp_stateless_reset_token);
|
||||
if (params->tp_flags & (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6))
|
||||
if (set & (1 << TPI_PREFERRED_ADDRESS))
|
||||
need += 4 + preferred_address_size(params);
|
||||
}
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
else if (params->tp_flags & TRAPA_QUANTUM_READY)
|
||||
else if (set & (1 << TPI_QUANTUM_READINESS))
|
||||
need += 4 + QUANTUM_READY_SZ;
|
||||
#endif
|
||||
|
||||
for (tpi = 0; tpi <= MAX_TPI; ++tpi)
|
||||
if ((NUMERIC_TRANS_PARAMS & (1 << tpi))
|
||||
&& params->tp_numerics_u.a[tpi2idx[tpi]] != def_vals[tpi])
|
||||
for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
|
||||
if (set & (1 << tpi))
|
||||
{
|
||||
if (params->tp_numerics_u.a[tpi2idx[tpi]] < max_vals[tpi])
|
||||
if (tpi > MAX_NUM_WITH_DEF_TPI
|
||||
|| params->tp_numerics[tpi] != def_vals[tpi])
|
||||
{
|
||||
bits[tpi] = vint_val2bits(params->tp_numerics_u.a[tpi2idx[tpi]]);
|
||||
need += 4 + (1 << bits[tpi]);
|
||||
if (params->tp_numerics[tpi] <= max_vals[tpi])
|
||||
{
|
||||
bits[tpi] = vint_val2bits(params->tp_numerics[tpi]);
|
||||
need += 4 + (1 << bits[tpi]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("numeric value is too large (%"PRIu64" vs maximum "
|
||||
"of %"PRIu64")", params->tp_numerics[tpi],
|
||||
max_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("numeric value is too large (%"PRIu64" vs maximum "
|
||||
"of %"PRIu64")", params->tp_numerics_u.a[tpi2idx[tpi]],
|
||||
max_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
set &= ~(1 << tpi); /* Don't write default value */
|
||||
}
|
||||
|
||||
if (params->tp_disable_active_migration != TP_DEF_DISABLE_ACTIVE_MIGRATION)
|
||||
need += 4 + 0;
|
||||
|
||||
if (params->tp_flags & TRAPA_QL_BITS_OLD)
|
||||
need += 4 + 0;
|
||||
else if (params->tp_flags & TRAPA_QL_BITS)
|
||||
need += 4 + 1;
|
||||
for (; tpi <= MAX_EMPTY_TPI; ++tpi)
|
||||
if (set & (1 << tpi))
|
||||
need += 4 + 0;
|
||||
|
||||
if (need > bufsz || need > UINT16_MAX)
|
||||
{
|
||||
|
@ -178,110 +260,65 @@ lsquic_tp_encode (const struct transport_params *params,
|
|||
|
||||
WRITE_UINT_TO_P(need - 2 + buf - p, 16);
|
||||
|
||||
for (tpi = 0; tpi <= MAX_TPI; ++tpi)
|
||||
if (NUMERIC_TRANS_PARAMS & (1 << tpi))
|
||||
for (tpi = 0; tpi <= LAST_TPI; ++tpi)
|
||||
if (set & (1 << tpi))
|
||||
{
|
||||
if (params->tp_numerics_u.a[tpi2idx[tpi]] != def_vals[tpi])
|
||||
{
|
||||
WRITE_UINT_TO_P(tpi, 16);
|
||||
WRITE_UINT_TO_P(1 << bits[tpi], 16);
|
||||
vint_write(p, params->tp_numerics_u.a[tpi2idx[tpi]], bits[tpi],
|
||||
1 << bits[tpi]);
|
||||
p += 1 << bits[tpi];
|
||||
}
|
||||
}
|
||||
else
|
||||
WRITE_UINT_TO_P(enum_2_tpi_val[tpi], 16);
|
||||
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:
|
||||
WRITE_UINT_TO_P(1 << bits[tpi], 16);
|
||||
vint_write(p, params->tp_numerics[tpi], bits[tpi],
|
||||
1 << bits[tpi]);
|
||||
p += 1 << bits[tpi];
|
||||
break;
|
||||
case TPI_ORIGINAL_CONNECTION_ID:
|
||||
if (params->tp_flags & TRAPA_ORIGINAL_CID)
|
||||
{
|
||||
WRITE_UINT_TO_P(TPI_ORIGINAL_CONNECTION_ID, 16);
|
||||
WRITE_UINT_TO_P(params->tp_original_cid.len, 16);
|
||||
WRITE_TO_P(params->tp_original_cid.idbuf,
|
||||
params->tp_original_cid.len);
|
||||
}
|
||||
WRITE_UINT_TO_P(params->tp_original_cid.len, 16);
|
||||
WRITE_TO_P(params->tp_original_cid.idbuf,
|
||||
params->tp_original_cid.len);
|
||||
break;
|
||||
case TPI_STATELESS_RESET_TOKEN:
|
||||
if (params->tp_flags & TRAPA_RESET_TOKEN)
|
||||
{
|
||||
WRITE_UINT_TO_P(TPI_STATELESS_RESET_TOKEN, 16);
|
||||
WRITE_UINT_TO_P(sizeof(params->tp_stateless_reset_token),
|
||||
16);
|
||||
WRITE_TO_P(params->tp_stateless_reset_token,
|
||||
sizeof(params->tp_stateless_reset_token));
|
||||
}
|
||||
WRITE_UINT_TO_P(sizeof(params->tp_stateless_reset_token), 16);
|
||||
WRITE_TO_P(params->tp_stateless_reset_token,
|
||||
sizeof(params->tp_stateless_reset_token));
|
||||
break;
|
||||
case TPI_PREFERRED_ADDRESS:
|
||||
if (params->tp_flags
|
||||
& (TRAPA_PREFADDR_IPv4|TRAPA_PREFADDR_IPv6))
|
||||
{
|
||||
WRITE_UINT_TO_P(TPI_PREFERRED_ADDRESS, 16);
|
||||
WRITE_UINT_TO_P(preferred_address_size(params), 16);
|
||||
if (params->tp_flags & TRAPA_PREFADDR_IPv4)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(p, 0, 6);
|
||||
p += 6;
|
||||
}
|
||||
if (params->tp_flags & TRAPA_PREFADDR_IPv6)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(p, 0, 18);
|
||||
p += 18;
|
||||
}
|
||||
*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));
|
||||
}
|
||||
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:
|
||||
if (params->tp_disable_active_migration != TP_DEF_DISABLE_ACTIVE_MIGRATION)
|
||||
{
|
||||
WRITE_UINT_TO_P(TPI_DISABLE_ACTIVE_MIGRATION, 16);
|
||||
WRITE_UINT_TO_P(0, 16);
|
||||
}
|
||||
WRITE_UINT_TO_P(0, 16);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (params->tp_flags & TRAPA_QL_BITS_OLD)
|
||||
{
|
||||
WRITE_UINT_TO_P(TPI_QL_BITS, 16);
|
||||
WRITE_UINT_TO_P(0, 16);
|
||||
}
|
||||
else if (params->tp_flags & TRAPA_QL_BITS)
|
||||
{
|
||||
WRITE_UINT_TO_P(TPI_QL_BITS, 16);
|
||||
WRITE_UINT_TO_P(1, 16);
|
||||
*p++ = !!params->tp_loss_bits;
|
||||
}
|
||||
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
if (params->tp_flags & TRAPA_QUANTUM_READY)
|
||||
{
|
||||
WRITE_UINT_TO_P(TPI_QUANTUM_READINESS, 16);
|
||||
WRITE_UINT_TO_P(QUANTUM_READY_SZ, 16);
|
||||
memset(p, 'Q', QUANTUM_READY_SZ);
|
||||
p += QUANTUM_READY_SZ;
|
||||
}
|
||||
case TPI_QUANTUM_READINESS:
|
||||
WRITE_UINT_TO_P(QUANTUM_READY_SZ, 16);
|
||||
memset(p, 'Q', QUANTUM_READY_SZ);
|
||||
p += QUANTUM_READY_SZ;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
assert(buf + need == p);
|
||||
return (int) (p - buf);
|
||||
|
@ -298,18 +335,15 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
|||
{
|
||||
const unsigned char *p, *end, *q;
|
||||
uint16_t len, param_id, tlen;
|
||||
enum transport_param_id tpi;
|
||||
unsigned set_of_ids;
|
||||
int s;
|
||||
uint64_t tmp64;
|
||||
|
||||
p = buf;
|
||||
end = buf + bufsz;
|
||||
|
||||
*params = TP_INITIALIZER();
|
||||
|
||||
if (is_server)
|
||||
params->tp_flags |= TRAPA_SERVER;
|
||||
|
||||
if (end - p < 2)
|
||||
return -1;
|
||||
READ_UINT(len, 16, p, 2);
|
||||
|
@ -337,43 +371,43 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
|||
p += 2;
|
||||
if (len > end - p)
|
||||
return -1;
|
||||
/* If we need to support parameter IDs 31 and up, we will need to
|
||||
* change this code:
|
||||
*/
|
||||
if (param_id < sizeof(set_of_ids) * 8)
|
||||
tpi = tpi_val_2_enum(param_id);
|
||||
if (tpi <= LAST_TPI)
|
||||
{
|
||||
/* Only check duplicates for IDs <= 31: all standard parameters
|
||||
* fit in a bitmask 32 bits wide.
|
||||
*/
|
||||
if (set_of_ids & (1 << param_id))
|
||||
if (set_of_ids & (1 << tpi))
|
||||
return -1;
|
||||
set_of_ids |= 1 << param_id;
|
||||
set_of_ids |= 1 << tpi;
|
||||
}
|
||||
else
|
||||
goto gt32;
|
||||
if (NUMERIC_TRANS_PARAMS & (1u << param_id))
|
||||
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:
|
||||
switch (len)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
s = vint_read(p, p + len,
|
||||
¶ms->tp_numerics_u.a[tpi2idx[param_id]]);
|
||||
s = vint_read(p, p + len, ¶ms->tp_numerics[tpi]);
|
||||
if (s == len)
|
||||
{
|
||||
if (params->tp_numerics_u.a[tpi2idx[param_id]]
|
||||
> max_vals[param_id])
|
||||
if (params->tp_numerics[tpi] > max_vals[tpi])
|
||||
{
|
||||
LSQ_DEBUG("numeric value of parameter 0x%X is too "
|
||||
"large (%"PRIu64" vs maximum of %"PRIu64,
|
||||
param_id,
|
||||
params->tp_numerics_u.a[tpi2idx[param_id]],
|
||||
max_vals[param_id]);
|
||||
param_id, params->tp_numerics[tpi], max_vals[tpi]);
|
||||
return -1;
|
||||
}
|
||||
p += s;
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -383,125 +417,85 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
|
|||
return -1;
|
||||
}
|
||||
default:
|
||||
LSQ_DEBUG("invalid length=%u for numeric transport parameter",
|
||||
len);
|
||||
LSQ_DEBUG("invalid length=%u for numeric transport "
|
||||
"parameter 0x%X", len, param_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gt32: switch (param_id)
|
||||
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)
|
||||
{
|
||||
case TPI_DISABLE_ACTIVE_MIGRATION:
|
||||
EXPECT_LEN(0);
|
||||
params->tp_disable_active_migration = 1;
|
||||
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));
|
||||
params->tp_flags |= TRAPA_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;
|
||||
params->tp_flags |= TRAPA_ORIGINAL_CID;
|
||||
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;
|
||||
if (params->tp_preferred_address.ipv4_port
|
||||
&& !lsquic_is_zero(params->tp_preferred_address.ipv4_addr,
|
||||
sizeof(params->tp_preferred_address.ipv4_addr)))
|
||||
params->tp_flags |= TRAPA_PREFADDR_IPv4;
|
||||
if (params->tp_preferred_address.ipv6_port
|
||||
&& !lsquic_is_zero(params->tp_preferred_address.ipv6_addr,
|
||||
sizeof(params->tp_preferred_address.ipv6_addr)))
|
||||
params->tp_flags |= TRAPA_PREFADDR_IPv6;
|
||||
break;
|
||||
case TPI_QL_BITS:
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
/* Old-school boolean */
|
||||
params->tp_flags |= TRAPA_QL_BITS;
|
||||
params->tp_loss_bits = 1;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
s = vint_read(p, p + len, &tmp64);
|
||||
if (s != len)
|
||||
{
|
||||
LSQ_DEBUG("cannot read the value of numeric transport "
|
||||
"param loss_bits of length %u", len);
|
||||
return -1;
|
||||
}
|
||||
if (!(tmp64 == 0 || tmp64 == 1))
|
||||
{
|
||||
LSQ_DEBUG("unexpected value of loss_bits TP: %"PRIu64,
|
||||
tmp64);
|
||||
return -1;
|
||||
}
|
||||
params->tp_loss_bits = tmp64;
|
||||
params->tp_flags |= TRAPA_QL_BITS;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
LSQ_DEBUG("preferred server address contains invalid "
|
||||
"CID length of %"PRIu16" bytes", tlen);
|
||||
return -1;
|
||||
}
|
||||
p += len;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,32 +512,40 @@ 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];
|
||||
|
||||
#define SEMICOLON "; "
|
||||
#define WRITE_ONE_PARAM(name, fmt) do { \
|
||||
nw = snprintf(buf, end - buf, #name ": " fmt SEMICOLON, params->tp_##name); \
|
||||
buf += nw; \
|
||||
if (buf >= end) \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
WRITE_ONE_PARAM(init_max_stream_data_bidi_local, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_stream_data_bidi_remote, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_stream_data_uni, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_data, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(max_idle_timeout, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_streams_bidi, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(init_max_streams_uni, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(max_packet_size, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(ack_delay_exponent, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(active_connection_id_limit, "%"PRIu64);
|
||||
WRITE_ONE_PARAM(disable_active_migration, "%hhd");
|
||||
#undef SEMICOLON
|
||||
#define SEMICOLON ""
|
||||
WRITE_ONE_PARAM(max_ack_delay, "%"PRIu64);
|
||||
if (params->tp_flags & TRAPA_RESET_TOKEN)
|
||||
for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
|
||||
if (params->tp_set & (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL))
|
||||
{
|
||||
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));
|
||||
|
@ -552,7 +554,7 @@ lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
|
|||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
if (params->tp_flags & TRAPA_RESET_TOKEN)
|
||||
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,
|
||||
|
@ -561,7 +563,7 @@ lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
|
|||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
if (params->tp_flags & TRAPA_PREFADDR_IPv4)
|
||||
if (lsquic_tp_has_pref_ipv4(params))
|
||||
{
|
||||
if (inet_ntop(AF_INET, params->tp_preferred_address.ipv4_addr,
|
||||
addr_str, sizeof(addr_str)))
|
||||
|
@ -573,7 +575,7 @@ lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (params->tp_flags & TRAPA_PREFADDR_IPv6)
|
||||
if (lsquic_tp_has_pref_ipv6(params))
|
||||
{
|
||||
if (inet_ntop(AF_INET6, params->tp_preferred_address.ipv6_addr,
|
||||
addr_str, sizeof(addr_str)))
|
||||
|
@ -585,15 +587,4 @@ lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (params->tp_flags & TRAPA_QL_BITS)
|
||||
{
|
||||
nw = snprintf(buf, end - buf, "; QL loss bits: %hhu",
|
||||
params->tp_loss_bits);
|
||||
buf += nw;
|
||||
if (buf >= end)
|
||||
return;
|
||||
}
|
||||
|
||||
#undef SEMICOLON
|
||||
#undef WRITE_ONE_PARAM
|
||||
}
|
||||
|
|
|
@ -6,98 +6,76 @@
|
|||
#ifndef LSQUIC_TRANS_PARAMS_H
|
||||
#define LSQUIC_TRANS_PARAMS_H 1
|
||||
|
||||
/* [draft-ietf-quic-transport-17], Section 18 */
|
||||
/* Transport parameters are grouped by the type of their values: numeric,
|
||||
* empty, and custom.
|
||||
*
|
||||
* The enum values are arbitrary. The literal transport parameter ID
|
||||
* *values* (e.g. 0x1057 for loss bits) are not exposed by the API.
|
||||
*/
|
||||
enum transport_param_id
|
||||
{
|
||||
TPI_ORIGINAL_CONNECTION_ID = 0,
|
||||
TPI_MAX_IDLE_TIMEOUT = 1,
|
||||
TPI_STATELESS_RESET_TOKEN = 2,
|
||||
TPI_MAX_PACKET_SIZE = 3,
|
||||
TPI_INIT_MAX_DATA = 4,
|
||||
TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL = 5,
|
||||
TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE = 6,
|
||||
TPI_INIT_MAX_STREAM_DATA_UNI = 7,
|
||||
TPI_INIT_MAX_STREAMS_BIDI = 8,
|
||||
TPI_INIT_MAX_STREAMS_UNI = 9,
|
||||
TPI_ACK_DELAY_EXPONENT = 10,
|
||||
TPI_MAX_ACK_DELAY = 11,
|
||||
TPI_DISABLE_ACTIVE_MIGRATION = 12,
|
||||
TPI_PREFERRED_ADDRESS = 13,
|
||||
TPI_ACTIVE_CONNECTION_ID_LIMIT = 14,
|
||||
#define MAX_TPI TPI_ACTIVE_CONNECTION_ID_LIMIT
|
||||
};
|
||||
/*
|
||||
* Numeric transport parameters that have default values:
|
||||
*/
|
||||
TPI_MAX_IDLE_TIMEOUT,
|
||||
TPI_MAX_PACKET_SIZE,
|
||||
TPI_INIT_MAX_DATA,
|
||||
TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL,
|
||||
TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE,
|
||||
TPI_INIT_MAX_STREAM_DATA_UNI,
|
||||
TPI_INIT_MAX_STREAMS_BIDI,
|
||||
TPI_INIT_MAX_STREAMS_UNI,
|
||||
TPI_ACK_DELAY_EXPONENT,
|
||||
TPI_MAX_ACK_DELAY,
|
||||
TPI_ACTIVE_CONNECTION_ID_LIMIT, MAX_NUM_WITH_DEF_TPI = TPI_ACTIVE_CONNECTION_ID_LIMIT,
|
||||
|
||||
#define NUMERIC_TRANS_PARAMS (\
|
||||
(1 << TPI_MAX_PACKET_SIZE) \
|
||||
|(1 << TPI_INIT_MAX_STREAMS_UNI) \
|
||||
|(1 << TPI_INIT_MAX_STREAMS_UNI) \
|
||||
|(1 << TPI_INIT_MAX_STREAMS_BIDI) \
|
||||
|(1 << TPI_INIT_MAX_DATA) \
|
||||
|(1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL) \
|
||||
|(1 << TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE) \
|
||||
|(1 << TPI_INIT_MAX_STREAM_DATA_UNI) \
|
||||
|(1 << TPI_MAX_IDLE_TIMEOUT) \
|
||||
|(1 << TPI_MAX_ACK_DELAY) \
|
||||
|(1 << TPI_ACK_DELAY_EXPONENT) \
|
||||
|(1 << TPI_ACTIVE_CONNECTION_ID_LIMIT) \
|
||||
)
|
||||
/*
|
||||
* Numeric transport parameters without default values:
|
||||
*/
|
||||
TPI_LOSS_BITS, MAX_NUMERIC_TPI = TPI_LOSS_BITS,
|
||||
|
||||
#define IQUIC_MAX_SUPP_VERS ((2<<7) - 4)/sizeof(uint32_t)
|
||||
/*
|
||||
* Empty transport parameters:
|
||||
*/
|
||||
TPI_DISABLE_ACTIVE_MIGRATION, MAX_EMPTY_TPI = TPI_DISABLE_ACTIVE_MIGRATION,
|
||||
|
||||
enum trapa_flags
|
||||
{
|
||||
TRAPA_RESET_TOKEN = 1 << 0, /* Reset token is set */
|
||||
TRAPA_SERVER = 1 << 1, /* Server transport parameters */
|
||||
TRAPA_PREFADDR_IPv4 = 1 << 2, /* Preferred IPv4 address is set */
|
||||
TRAPA_PREFADDR_IPv6 = 1 << 3, /* Preferred IPv6 address is set */
|
||||
TRAPA_ORIGINAL_CID = 1 << 4, /* Original CID is set */
|
||||
/*
|
||||
* Custom handlers:
|
||||
*/
|
||||
TPI_PREFERRED_ADDRESS,
|
||||
TPI_ORIGINAL_CONNECTION_ID,
|
||||
#if LSQUIC_TEST_QUANTUM_READINESS
|
||||
#define QUANTUM_READY_SZ 1200
|
||||
/* https://github.com/quicwg/base-drafts/wiki/Quantum-Readiness-test */
|
||||
#define TPI_QUANTUM_READINESS 3127
|
||||
TRAPA_QUANTUM_READY = 1 << 5, /* Include "Quantum Readiness" TP */
|
||||
#define QUANTUM_READY_SZ 1200
|
||||
TPI_QUANTUM_READINESS,
|
||||
#endif
|
||||
#define TPI_QL_BITS 0x1057 /* 1057 is 133t for "lost" */
|
||||
TRAPA_QL_BITS = 1 << 6, /* tp_loss_bits contains valid value */
|
||||
TRAPA_QL_BITS_OLD = 1 << 7, /* Send old-school boolean loss_bits TP.
|
||||
* Not set on decoded transport parameters.
|
||||
*/
|
||||
TPI_STATELESS_RESET_TOKEN, LAST_TPI = TPI_STATELESS_RESET_TOKEN
|
||||
};
|
||||
|
||||
|
||||
struct transport_params
|
||||
{
|
||||
enum trapa_flags tp_flags;
|
||||
/* Which transport parameters values are set: */
|
||||
unsigned tp_set;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint64_t init_max_stream_data_bidi_local;
|
||||
uint64_t init_max_stream_data_bidi_remote;
|
||||
uint64_t init_max_stream_data_uni;
|
||||
uint64_t init_max_data;
|
||||
uint64_t max_idle_timeout;
|
||||
uint64_t init_max_streams_bidi;
|
||||
uint64_t init_max_streams_uni;
|
||||
uint64_t max_packet_size;
|
||||
uint64_t ack_delay_exponent;
|
||||
uint64_t max_ack_delay;
|
||||
uint64_t active_connection_id_limit;
|
||||
} s;
|
||||
uint64_t a[11];
|
||||
} tp_numerics_u;
|
||||
#define tp_init_max_stream_data_bidi_local tp_numerics_u.s.init_max_stream_data_bidi_local
|
||||
#define tp_init_max_stream_data_bidi_remote tp_numerics_u.s.init_max_stream_data_bidi_remote
|
||||
#define tp_init_max_stream_data_uni tp_numerics_u.s.init_max_stream_data_uni
|
||||
#define tp_init_max_data tp_numerics_u.s.init_max_data
|
||||
#define tp_max_idle_timeout tp_numerics_u.s.max_idle_timeout
|
||||
#define tp_init_max_streams_bidi tp_numerics_u.s.init_max_streams_bidi
|
||||
#define tp_init_max_streams_uni tp_numerics_u.s.init_max_streams_uni
|
||||
#define tp_max_packet_size tp_numerics_u.s.max_packet_size
|
||||
#define tp_ack_delay_exponent tp_numerics_u.s.ack_delay_exponent
|
||||
#define tp_max_ack_delay tp_numerics_u.s.max_ack_delay
|
||||
#define tp_active_connection_id_limit tp_numerics_u.s.active_connection_id_limit
|
||||
/* Which transport parameters were present (set by the decoder): */
|
||||
unsigned tp_decoded;
|
||||
|
||||
uint64_t tp_numerics[MAX_NUMERIC_TPI + 1];
|
||||
|
||||
#define tp_init_max_stream_data_bidi_local tp_numerics[TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL]
|
||||
#define tp_init_max_stream_data_bidi_remote tp_numerics[TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE]
|
||||
#define tp_init_max_stream_data_uni tp_numerics[TPI_INIT_MAX_STREAM_DATA_UNI]
|
||||
#define tp_init_max_data tp_numerics[TPI_INIT_MAX_DATA]
|
||||
#define tp_max_idle_timeout tp_numerics[TPI_MAX_IDLE_TIMEOUT]
|
||||
#define tp_init_max_streams_bidi tp_numerics[TPI_INIT_MAX_STREAMS_BIDI]
|
||||
#define tp_init_max_streams_uni tp_numerics[TPI_INIT_MAX_STREAMS_UNI]
|
||||
#define tp_max_packet_size tp_numerics[TPI_MAX_PACKET_SIZE]
|
||||
#define tp_ack_delay_exponent tp_numerics[TPI_ACK_DELAY_EXPONENT]
|
||||
#define tp_max_ack_delay tp_numerics[TPI_MAX_ACK_DELAY]
|
||||
#define tp_active_connection_id_limit tp_numerics[TPI_ACTIVE_CONNECTION_ID_LIMIT]
|
||||
#define tp_loss_bits tp_numerics[TPI_LOSS_BITS]
|
||||
|
||||
unsigned char tp_loss_bits; /* Valid values 0, 1. Set if TRAPA_QL_BITS is set. */
|
||||
signed char tp_disable_active_migration;
|
||||
uint8_t tp_stateless_reset_token[IQUIC_SRESET_TOKEN_SZ];
|
||||
struct {
|
||||
uint8_t ipv4_addr[4];
|
||||
|
@ -127,6 +105,7 @@ struct transport_params
|
|||
#define TP_MAX_MAX_ACK_DELAY ((1u << 14) - 1)
|
||||
|
||||
#define TP_DEFAULT_VALUES \
|
||||
.tp_set = ((1 << (MAX_NUM_WITH_DEF_TPI + 1)) - 1), \
|
||||
.tp_active_connection_id_limit = TP_DEF_ACTIVE_CONNECTION_ID_LIMIT, \
|
||||
.tp_max_idle_timeout = TP_DEF_MAX_IDLE_TIMEOUT, \
|
||||
.tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY, \
|
||||
|
@ -135,7 +114,6 @@ struct transport_params
|
|||
.tp_init_max_streams_bidi = TP_DEF_INIT_MAX_STREAMS_BIDI, \
|
||||
.tp_init_max_streams_uni = TP_DEF_INIT_MAX_STREAMS_UNI, \
|
||||
.tp_init_max_data = TP_DEF_INIT_MAX_DATA, \
|
||||
.tp_disable_active_migration = TP_DEF_DISABLE_ACTIVE_MIGRATION, \
|
||||
.tp_init_max_stream_data_bidi_local = TP_DEF_INIT_MAX_STREAM_DATA_BIDI_LOCAL, \
|
||||
.tp_init_max_stream_data_bidi_remote = TP_DEF_INIT_MAX_STREAM_DATA_BIDI_REMOTE, \
|
||||
.tp_init_max_stream_data_uni = TP_DEF_INIT_MAX_STREAM_DATA_UNI
|
||||
|
@ -143,7 +121,7 @@ struct transport_params
|
|||
#define TP_INITIALIZER() (struct transport_params) { TP_DEFAULT_VALUES }
|
||||
|
||||
int
|
||||
lsquic_tp_encode (const struct transport_params *,
|
||||
lsquic_tp_encode (const struct transport_params *, int is_server,
|
||||
unsigned char *buf, size_t bufsz);
|
||||
|
||||
int
|
||||
|
@ -158,4 +136,10 @@ lsquic_tp_decode (const unsigned char *buf, size_t bufsz,
|
|||
void
|
||||
lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz);
|
||||
|
||||
int
|
||||
lsquic_tp_has_pref_ipv4 (const struct transport_params *);
|
||||
|
||||
int
|
||||
lsquic_tp_has_pref_ipv6 (const struct transport_params *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,8 @@ struct trapa_test
|
|||
} flags;
|
||||
struct transport_params params;
|
||||
size_t enc_len, dec_len;
|
||||
unsigned addl_set;
|
||||
int is_server;
|
||||
int expect_decode_err;
|
||||
unsigned char encoded[ENC_BUF_SZ];
|
||||
};
|
||||
|
@ -53,13 +55,20 @@ static const struct trapa_test tests[] =
|
|||
.line = __LINE__,
|
||||
.flags = TEST_ENCODE | TEST_DECODE,
|
||||
.params = {
|
||||
.tp_flags = 0,
|
||||
.tp_set = (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL)
|
||||
| (1 << TPI_INIT_MAX_DATA)
|
||||
| (1 << TPI_MAX_IDLE_TIMEOUT)
|
||||
| (1 << TPI_MAX_ACK_DELAY)
|
||||
| (1 << TPI_MAX_PACKET_SIZE)
|
||||
| (1 << TPI_ACK_DELAY_EXPONENT)
|
||||
| (1 << TPI_ACTIVE_CONNECTION_ID_LIMIT),
|
||||
.tp_init_max_stream_data_bidi_local = 0x12348877,
|
||||
.tp_init_max_data = 0xAABB,
|
||||
.tp_max_idle_timeout = 10 * 1000,
|
||||
.tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY,
|
||||
.tp_active_connection_id_limit = 7,
|
||||
},
|
||||
.is_server = 0,
|
||||
.enc_len = 39,
|
||||
.encoded =
|
||||
/* Overall length */ "\x00\x25"
|
||||
|
@ -94,12 +103,12 @@ static const struct trapa_test tests[] =
|
|||
.flags = TEST_ENCODE | TEST_DECODE,
|
||||
.params = {
|
||||
TP_DEFAULT_VALUES,
|
||||
.tp_flags = TRAPA_SERVER,
|
||||
.tp_init_max_data = 0x123456,
|
||||
.tp_init_max_stream_data_bidi_local = 0xABCDEF88,
|
||||
.tp_disable_active_migration = 1,
|
||||
.tp_max_packet_size = 0x333,
|
||||
},
|
||||
.is_server = 1,
|
||||
.addl_set = 1 << TPI_DISABLE_ACTIVE_MIGRATION,
|
||||
.enc_len = 32,
|
||||
.encoded =
|
||||
/* Overall length */ "\x00\x1E"
|
||||
|
@ -117,7 +126,6 @@ static const struct trapa_test tests[] =
|
|||
.flags = TEST_DECODE,
|
||||
.params = {
|
||||
TP_DEFAULT_VALUES,
|
||||
.tp_flags = TRAPA_SERVER | TRAPA_PREFADDR_IPv4 | TRAPA_PREFADDR_IPv6,
|
||||
.tp_max_ack_delay = 25,
|
||||
.tp_max_packet_size = 0x333,
|
||||
.tp_preferred_address = {
|
||||
|
@ -129,6 +137,8 @@ static const struct trapa_test tests[] =
|
|||
.srst = "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F",
|
||||
},
|
||||
},
|
||||
.is_server = 1,
|
||||
.addl_set = 1 << TPI_PREFERRED_ADDRESS,
|
||||
.enc_len = 0x3E + 2,
|
||||
.encoded =
|
||||
/* Overall length */ "\x00\x3E"
|
||||
|
@ -154,9 +164,8 @@ params_are_equal (const struct transport_params *a,
|
|||
const struct transport_params *b)
|
||||
{
|
||||
#define MCMP(f) 0 == memcmp(&a->f, &b->f, sizeof(a->f))
|
||||
return a->tp_flags == b->tp_flags
|
||||
&& MCMP(tp_numerics_u)
|
||||
&& a->tp_disable_active_migration == b->tp_disable_active_migration
|
||||
return MCMP(tp_numerics)
|
||||
&& MCMP(tp_set)
|
||||
&& MCMP(tp_stateless_reset_token)
|
||||
&& MCMP(tp_preferred_address.ipv4_addr)
|
||||
&& MCMP(tp_preferred_address.ipv6_addr)
|
||||
|
@ -175,14 +184,18 @@ params_are_equal (const struct transport_params *a,
|
|||
static void
|
||||
run_test (const struct trapa_test *test)
|
||||
{
|
||||
struct transport_params source_params;
|
||||
struct transport_params decoded_params;
|
||||
size_t dec_len;
|
||||
int s;
|
||||
unsigned char buf[ENC_BUF_SZ];
|
||||
|
||||
source_params = test->params;
|
||||
source_params.tp_set |= test->addl_set;
|
||||
|
||||
if (test->flags & TEST_ENCODE)
|
||||
{
|
||||
s = lsquic_tp_encode(&test->params, buf, sizeof(buf));
|
||||
s = lsquic_tp_encode(&source_params, test->is_server, buf, sizeof(buf));
|
||||
assert(s > 0);
|
||||
assert((size_t) s == test->enc_len);
|
||||
assert(0 == memcmp(test->encoded, buf, s));
|
||||
|
@ -195,12 +208,16 @@ run_test (const struct trapa_test *test)
|
|||
else
|
||||
dec_len = sizeof(buf);
|
||||
s = lsquic_tp_decode(test->encoded, dec_len,
|
||||
test->params.tp_flags & TRAPA_SERVER, &decoded_params);
|
||||
test->is_server, &decoded_params);
|
||||
if (!test->expect_decode_err)
|
||||
{
|
||||
assert(s > 0);
|
||||
assert((size_t) s == test->enc_len);
|
||||
s = params_are_equal(&test->params, &decoded_params);
|
||||
/* The decoder initializes all default values, so set the flag
|
||||
* accordingly:
|
||||
*/
|
||||
source_params.tp_set |= ((1 << (MAX_NUM_WITH_DEF_TPI + 1)) - 1);
|
||||
s = params_are_equal(&source_params, &decoded_params);
|
||||
assert(s);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue