Release 2.18.1

- [FEATURE] Implement the "QUIC bit grease" extension.
- [BUGFIX] Selecting CID used for logging on client.
- [BUGFIX] Header protection assertion.
- [BUGFIX] Server: enable SSL key logging when cert lookup callback
  is not set.
- Remove some dead code.
This commit is contained in:
Dmitri Tikhonov 2020-07-14 08:26:58 -04:00
parent 67507cc4b6
commit 692a91022d
13 changed files with 82 additions and 16 deletions

View file

@ -1,3 +1,12 @@
2020-07-14
- 2.18.1
- [FEATURE] Implement the "QUIC bit grease" extension.
- [BUGFIX] Selecting CID used for logging on client.
- [BUGFIX] Header protection assertion.
- [BUGFIX] Server: enable SSL key logging when cert lookup callback
is not set.
- Remove some dead code.
2020-07-06 2020-07-06
- 2.18.0 - 2.18.0
- [API] Rename "0-RTT" to "session resumption." In IETF QUIC, "0-RTT" - [API] Rename "0-RTT" to "session resumption." In IETF QUIC, "0-RTT"

View file

@ -1920,6 +1920,11 @@ set_engine_option (struct lsquic_engine_settings *settings,
settings->es_allow_migration = atoi(val); settings->es_allow_migration = atoi(val);
return 0; return 0;
} }
if (0 == strncmp(name, "grease_quic_bit", 15))
{
settings->es_grease_quic_bit = atoi(val);
return 0;
}
break; break;
case 16: case 16:
if (0 == strncmp(name, "proc_time_thresh", 16)) if (0 == strncmp(name, "proc_time_thresh", 16))

View file

@ -752,6 +752,14 @@ settings structure:
Default value is :macro:`LSQUIC_DF_NOPROGRESS_TIMEOUT_SERVER` in server Default value is :macro:`LSQUIC_DF_NOPROGRESS_TIMEOUT_SERVER` in server
mode and :macro:`LSQUIC_DF_NOPROGRESS_TIMEOUT_CLIENT` in client mode. mode and :macro:`LSQUIC_DF_NOPROGRESS_TIMEOUT_CLIENT` in client mode.
.. member:: int es_grease_quic_bit
Enable the "QUIC bit grease" extension. When set to a true value,
lsquic will grease the QUIC bit on the outgoing QUIC packets if
the peer sent the "grease_quic_bit" transport parameter.
Default value is :macro:`LSQUIC_DF_GREASE_QUIC_BIT`
To initialize the settings structure to library defaults, use the following To initialize the settings structure to library defaults, use the following
convenience function: convenience function:
@ -938,6 +946,11 @@ out of date. Please check your :file:`lsquic.h` for actual values.*
By default, do not use no-progress timeout on the client. By default, do not use no-progress timeout on the client.
.. macro:: LSQUIC_DF_GREASE_QUIC_BIT
By default, greasing the QUIC bit is enabled (if peer sent
the "grease_quic_bit" transport parameter).
Receiving Packets Receiving Packets
----------------- -----------------

View file

@ -26,7 +26,7 @@ author = u'LiteSpeed Technologies'
# The short X.Y version # The short X.Y version
version = u'2.18' version = u'2.18'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
release = u'2.18.0' release = u'2.18.1'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------

View file

@ -25,7 +25,7 @@ extern "C" {
#define LSQUIC_MAJOR_VERSION 2 #define LSQUIC_MAJOR_VERSION 2
#define LSQUIC_MINOR_VERSION 18 #define LSQUIC_MINOR_VERSION 18
#define LSQUIC_PATCH_VERSION 0 #define LSQUIC_PATCH_VERSION 1
/** /**
* Engine flags: * Engine flags:
@ -101,7 +101,7 @@ enum lsquic_version
}; };
/** /**
* We currently support versions 43, 46, 50, Draft-27, and Draft-28. * We currently support versions 43, 46, 50, Draft-27, Draft-28, and Draft-29.
* @see lsquic_version * @see lsquic_version
*/ */
#define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1) #define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1)
@ -344,6 +344,12 @@ typedef struct ssl_ctx_st * (*lsquic_lookup_cert_f)(
/** By default, incoming packet size is not limited. */ /** By default, incoming packet size is not limited. */
#define LSQUIC_DF_MAX_UDP_PAYLOAD_SIZE_RX 0 #define LSQUIC_DF_MAX_UDP_PAYLOAD_SIZE_RX 0
/**
* By default, greasing the QUIC bit is enabled (if peer sent
* the "grease_quic_bit" transport parameter).
*/
#define LSQUIC_DF_GREASE_QUIC_BIT 1
/** By default, drop no-progress connections after 60 seconds on the server */ /** By default, drop no-progress connections after 60 seconds on the server */
#define LSQUIC_DF_NOPROGRESS_TIMEOUT_SERVER 60 #define LSQUIC_DF_NOPROGRESS_TIMEOUT_SERVER 60
@ -803,6 +809,15 @@ struct lsquic_engine_settings {
* Default value is @ref LSQUIC_DF_MAX_UDP_PAYLOAD_SIZE_RX * Default value is @ref LSQUIC_DF_MAX_UDP_PAYLOAD_SIZE_RX
*/ */
unsigned short es_max_udp_payload_size_rx; unsigned short es_max_udp_payload_size_rx;
/**
* Enable the "QUIC bit grease" extension. When set to a true value,
* lsquic will grease the QUIC bit on the outgoing QUIC packets if
* the peer sent the "grease_quic_bit" transport parameter.
*
* Default value is @ref LSQUIC_DF_GREASE_QUIC_BIT
*/
int es_grease_quic_bit;
}; };
/* Initialize `settings' to default values */ /* Initialize `settings' to default values */

View file

@ -273,6 +273,7 @@ struct enc_sess_iquic
struct lsquic_packet_out * struct lsquic_packet_out *
esi_hp_batch_packets[HP_BATCH_SIZE]; esi_hp_batch_packets[HP_BATCH_SIZE];
unsigned char esi_hp_batch_samples[HP_BATCH_SIZE][SAMPLE_SZ]; unsigned char esi_hp_batch_samples[HP_BATCH_SIZE][SAMPLE_SZ];
unsigned char esi_grease;
}; };
@ -792,6 +793,7 @@ iquic_esfi_create_client (const char *hostname,
enc_sess->esi_odcid = *dcid; enc_sess->esi_odcid = *dcid;
enc_sess->esi_flags |= ESI_ODCID; enc_sess->esi_flags |= ESI_ODCID;
enc_sess->esi_grease = 0xFF;
LSQ_DEBUGC("created client, DCID: %"CID_FMT, CID_BITS(dcid)); LSQ_DEBUGC("created client, DCID: %"CID_FMT, CID_BITS(dcid));
{ {
@ -878,6 +880,7 @@ iquic_esfi_create_server (struct lsquic_engine_public *enpub,
enc_sess->esi_cryst_if = cryst_if; enc_sess->esi_cryst_if = cryst_if;
enc_sess->esi_enpub = enpub; enc_sess->esi_enpub = enpub;
enc_sess->esi_conn = lconn; enc_sess->esi_conn = lconn;
enc_sess->esi_grease = 0xFF;
if (odcid) if (odcid)
{ {
@ -1259,6 +1262,8 @@ iquic_esfi_init_server (enc_session_t *enc_session_p)
return -1; return -1;
} }
maybe_setup_key_logging(enc_sess); maybe_setup_key_logging(enc_sess);
if (!enc_sess->esi_enpub->enp_lookup_cert && enc_sess->esi_keylog_handle)
SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
transpa_len = gen_trans_params(enc_sess, u.trans_params, transpa_len = gen_trans_params(enc_sess, u.trans_params,
sizeof(u.trans_params)); sizeof(u.trans_params));
@ -1711,6 +1716,17 @@ get_peer_transport_params (struct enc_sess_iquic *enc_sess)
else else
LSQ_DEBUG("no QL bits"); LSQ_DEBUG("no QL bits");
if (trans_params->tp_set & (1 << TPI_GREASE_QUIC_BIT))
{
if (enc_sess->esi_enpub->enp_settings.es_grease_quic_bit)
{
LSQ_DEBUG("will grease the QUIC bit");
enc_sess->esi_grease = ~QUIC_BIT;
}
else
LSQ_DEBUG("greasing turned off: won't grease the QUIC bit");
}
return 0; return 0;
} }
@ -1980,6 +1996,7 @@ iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
goto err; goto err;
if (enc_level == ENC_LEV_FORW) if (enc_level == ENC_LEV_FORW)
dst[0] |= enc_sess->esi_key_phase << 2; dst[0] |= enc_sess->esi_key_phase << 2;
dst[0] &= enc_sess->esi_grease | packet_out->po_path->np_dcid.idbuf[0];
if (s_log_seal_and_open) if (s_log_seal_and_open)
{ {

View file

@ -356,6 +356,7 @@ lsquic_engine_init_settings (struct lsquic_engine_settings *settings,
settings->es_spin = LSQUIC_DF_SPIN; settings->es_spin = LSQUIC_DF_SPIN;
settings->es_delayed_acks = LSQUIC_DF_DELAYED_ACKS; settings->es_delayed_acks = LSQUIC_DF_DELAYED_ACKS;
settings->es_timestamps = LSQUIC_DF_TIMESTAMPS; settings->es_timestamps = LSQUIC_DF_TIMESTAMPS;
settings->es_grease_quic_bit = LSQUIC_DF_GREASE_QUIC_BIT;
} }

View file

@ -3825,6 +3825,9 @@ generate_connection_close_packet (struct ietf_full_conn *conn)
struct lsquic_packet_out *packet_out; struct lsquic_packet_out *packet_out;
int sz; int sz;
/* FIXME Select PNS based on handshake status (possible on the client): if
* appropriate keys are not available, encryption will fail.
*/
packet_out = lsquic_send_ctl_new_packet_out(&conn->ifc_send_ctl, 0, PNS_APP, packet_out = lsquic_send_ctl_new_packet_out(&conn->ifc_send_ctl, 0, PNS_APP,
CUR_NPATH(conn)); CUR_NPATH(conn));
if (!packet_out) if (!packet_out)
@ -6610,7 +6613,8 @@ ietf_full_conn_ci_packet_not_sent (struct lsquic_conn *lconn,
struct lsquic_packet_out *packet_out) struct lsquic_packet_out *packet_out)
{ {
#ifndef NDEBUG #ifndef NDEBUG
assert(packet_out->po_lflags & POL_HEADER_PROT); if (packet_out->po_flags & PO_ENCRYPTED)
assert(packet_out->po_lflags & POL_HEADER_PROT);
#endif #endif
struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn; struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn;
lsquic_send_ctl_delayed_one(&conn->ifc_send_ctl, packet_out); lsquic_send_ctl_delayed_one(&conn->ifc_send_ctl, packet_out);
@ -6625,7 +6629,8 @@ pre_hsk_packet_sent_or_delayed (struct ietf_full_conn *conn,
const struct lsquic_packet_out *packet_out) const struct lsquic_packet_out *packet_out)
{ {
#ifndef NDEBUG #ifndef NDEBUG
assert(packet_out->po_lflags & POL_HEADER_PROT); if (packet_out->po_flags & PO_ENCRYPTED)
assert(packet_out->po_lflags & POL_HEADER_PROT);
#endif #endif
/* Once IFC_IGNORE_INIT is set, the pre-hsk wrapper is removed: */ /* Once IFC_IGNORE_INIT is set, the pre-hsk wrapper is removed: */
assert(!(conn->ifc_flags & IFC_IGNORE_INIT)); assert(!(conn->ifc_flags & IFC_IGNORE_INIT));
@ -7192,7 +7197,7 @@ ietf_full_conn_ci_get_log_cid (const struct lsquic_conn *lconn)
else else
return CN_SCID(lconn); return CN_SCID(lconn);
} }
if (CUR_DCID(conn)->len) if (CN_SCID(lconn)->len)
return CN_SCID(lconn); return CN_SCID(lconn);
else else
return CUR_DCID(conn); return CUR_DCID(conn);

View file

@ -28,4 +28,6 @@
*/ */
#define IQUIC_MAX_OUT_PACKET_SZ ((1u << 14) - 1) #define IQUIC_MAX_OUT_PACKET_SZ ((1u << 14) - 1)
#define QUIC_BIT 0x40
#endif #endif

View file

@ -264,7 +264,7 @@ gen_short_pkt_header (const struct lsquic_conn *lconn,
if (need > bufsz) if (need > bufsz)
return -1; return -1;
buf[0] = 0x40 buf[0] = QUIC_BIT
| (lsquic_packet_out_spin_bit(packet_out) << 5) | (lsquic_packet_out_spin_bit(packet_out) << 5)
| (lsquic_packet_out_square_bit(packet_out) << 4) | (lsquic_packet_out_square_bit(packet_out) << 4)
| (lsquic_packet_out_loss_bit(packet_out) << 3) | (lsquic_packet_out_loss_bit(packet_out) << 3)
@ -2007,7 +2007,7 @@ lsquic_ietf_v1_gen_ver_nego_pkt (unsigned char *buf, size_t bufsz,
if (need > bufsz) if (need > bufsz)
return -1; return -1;
*buf++ = 0x80 | 0x40 | rand; *buf++ = 0x80 | QUIC_BIT | rand;
memset(buf, 0, 4); memset(buf, 0, 4);
buf += 4; buf += 4;

View file

@ -3869,15 +3869,7 @@ stream_uh_in_gquic (struct lsquic_stream *stream,
LSQ_DEBUG("received uncompressed headers"); LSQ_DEBUG("received uncompressed headers");
stream->stream_flags |= STREAM_HAVE_UH; stream->stream_flags |= STREAM_HAVE_UH;
if (uh->uh_flags & UH_FIN) if (uh->uh_flags & UH_FIN)
{
/* IETF QUIC only sets UH_FIN for a pushed stream on the server to
* mark request as done:
*/
if (stream->sm_bflags & SMBF_IETF)
assert((stream->sm_bflags & SMBF_SERVER)
&& lsquic_stream_is_pushed(stream));
stream->stream_flags |= STREAM_FIN_RECVD|STREAM_HEAD_IN_FIN; stream->stream_flags |= STREAM_FIN_RECVD|STREAM_HEAD_IN_FIN;
}
stream->uh = uh; stream->uh = uh;
if (uh->uh_oth_stream_id == 0) if (uh->uh_oth_stream_id == 0)
{ {

View file

@ -58,6 +58,7 @@ tpi_val_2_enum (uint64_t tpi_val)
case 0xC37: return TPI_QUANTUM_READINESS; case 0xC37: return TPI_QUANTUM_READINESS;
#endif #endif
case 0x1057: return TPI_LOSS_BITS; case 0x1057: return TPI_LOSS_BITS;
case 0x2AB2: return TPI_GREASE_QUIC_BIT;
case 0xDE1A: return TPI_MIN_ACK_DELAY; case 0xDE1A: return TPI_MIN_ACK_DELAY;
case 0x7157: return TPI_TIMESTAMPS; case 0x7157: return TPI_TIMESTAMPS;
default: return INT_MAX; default: return INT_MAX;
@ -90,6 +91,7 @@ static const unsigned enum_2_tpi_val[LAST_TPI + 1] =
[TPI_LOSS_BITS] = 0x1057, [TPI_LOSS_BITS] = 0x1057,
[TPI_MIN_ACK_DELAY] = 0xDE1A, [TPI_MIN_ACK_DELAY] = 0xDE1A,
[TPI_TIMESTAMPS] = 0x7157, [TPI_TIMESTAMPS] = 0x7157,
[TPI_GREASE_QUIC_BIT] = 0x2AB2,
}; };
@ -118,6 +120,7 @@ const char * const lsquic_tpi2str[LAST_TPI + 1] =
[TPI_LOSS_BITS] = "loss_bits", [TPI_LOSS_BITS] = "loss_bits",
[TPI_MIN_ACK_DELAY] = "min_ack_delay", [TPI_MIN_ACK_DELAY] = "min_ack_delay",
[TPI_TIMESTAMPS] = "timestamps", [TPI_TIMESTAMPS] = "timestamps",
[TPI_GREASE_QUIC_BIT] = "grease_quic_bit",
}; };
#define tpi2str lsquic_tpi2str #define tpi2str lsquic_tpi2str
@ -410,6 +413,7 @@ lsquic_tp_encode (const struct transport_params *params, int is_server,
break; break;
case TPI_DISABLE_ACTIVE_MIGRATION: case TPI_DISABLE_ACTIVE_MIGRATION:
case TPI_TIMESTAMPS: case TPI_TIMESTAMPS:
case TPI_GREASE_QUIC_BIT:
*p++ = 0; *p++ = 0;
break; break;
#if LSQUIC_TEST_QUANTUM_READINESS #if LSQUIC_TEST_QUANTUM_READINESS
@ -533,6 +537,7 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
break; break;
case TPI_DISABLE_ACTIVE_MIGRATION: case TPI_DISABLE_ACTIVE_MIGRATION:
case TPI_TIMESTAMPS: case TPI_TIMESTAMPS:
case TPI_GREASE_QUIC_BIT:
EXPECT_LEN(0); EXPECT_LEN(0);
break; break;
case TPI_STATELESS_RESET_TOKEN: case TPI_STATELESS_RESET_TOKEN:
@ -919,6 +924,7 @@ lsquic_tp_encode_27 (const struct transport_params *params, int is_server,
break; break;
case TPI_DISABLE_ACTIVE_MIGRATION: case TPI_DISABLE_ACTIVE_MIGRATION:
case TPI_TIMESTAMPS: case TPI_TIMESTAMPS:
case TPI_GREASE_QUIC_BIT:
*p++ = 0; *p++ = 0;
break; break;
#if LSQUIC_TEST_QUANTUM_READINESS #if LSQUIC_TEST_QUANTUM_READINESS

View file

@ -39,6 +39,7 @@ enum transport_param_id
* Empty transport parameters: * Empty transport parameters:
*/ */
TPI_TIMESTAMPS, TPI_TIMESTAMPS,
TPI_GREASE_QUIC_BIT,
TPI_DISABLE_ACTIVE_MIGRATION, MAX_EMPTY_TPI = TPI_DISABLE_ACTIVE_MIGRATION, TPI_DISABLE_ACTIVE_MIGRATION, MAX_EMPTY_TPI = TPI_DISABLE_ACTIVE_MIGRATION,
/* /*