Release 3.3.0

This commit is contained in:
George Wang 2023-01-04 15:21:42 -05:00
parent b5efa50a5a
commit 48365d5741
12 changed files with 82 additions and 42 deletions

View file

@ -1,10 +1,20 @@
2023-01-04
- 3.3.0
- Improve path validation logic to avoid sending padded packet to unverified
peer, follow 3X anti-amplification rule.
- Optimize application callback when STOP_SENDING frame received.
- Improve new connection callback logic.
- Improve handling of closed connection.
- Update BoringSSL to the most recent version.
- Fix memory leaks in gquic handshake and packet handling.
- Update ls-qpack to 2.5.1, ls-hpack to 2.3.1 to address compiler warnings
2022-10-20 2022-10-20
- 3.2.0 - 3.2.0
- Update ls-qpack to 2.5.0 to address a decoder bug - Update ls-qpack to 2.5.0 to address a decoder bug
- Assertion failure if poison packet was acked - Assertion failure if poison packet was acked
- Fix packet_in pool memory leak - Fix packet_in pool memory leak
2022-08-16 2022-08-16
- 3.1.2 - 3.1.2
- Update ls-qpack to 2.4.0 to address a use-after-free bug - Update ls-qpack to 2.4.0 to address a use-after-free bug
@ -14,7 +24,6 @@
- Fix IPv6 MTU detection - Fix IPv6 MTU detection
- Fix wrong size used in packet regeneration. - Fix wrong size used in packet regeneration.
2022-05-13 2022-05-13
- 3.1.1 - 3.1.1
- Fix memory leak in processing stream frames (isse #368) - Fix memory leak in processing stream frames (isse #368)

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc Copyright (c) 2017 - 2023 LiteSpeed Technologies Inc
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -49,8 +49,9 @@ You may need to install pre-requisites like zlib and libevent.
2. Use specific BoringSSL version 2. Use specific BoringSSL version
``` ```
git checkout a9670a8b476470e6f874fef3554e8059683e1413 git checkout 31bad2514d21f6207f3925ba56754611c462a873
``` ```
Or, just try the latest master branch.
3. Compile the library 3. Compile the library

View file

@ -20,13 +20,13 @@
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = u'lsquic' project = u'lsquic'
copyright = u'2022, LiteSpeed Technologies' copyright = u'2023, LiteSpeed Technologies'
author = u'LiteSpeed Technologies' author = u'LiteSpeed Technologies'
# The short X.Y version # The short X.Y version
version = u'3.2' version = u'3.3'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
release = u'3.2.0' release = u'3.3.0'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------

View file

@ -1,4 +1,6 @@
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ /* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
/* Copyright (c) 2017 - 2023 LiteSpeed Technologies Inc. See LICENSE. */
#ifndef __LSQUIC_H__ #ifndef __LSQUIC_H__
#define __LSQUIC_H__ #define __LSQUIC_H__
@ -24,7 +26,7 @@ extern "C" {
#endif #endif
#define LSQUIC_MAJOR_VERSION 3 #define LSQUIC_MAJOR_VERSION 3
#define LSQUIC_MINOR_VERSION 2 #define LSQUIC_MINOR_VERSION 3
#define LSQUIC_PATCH_VERSION 0 #define LSQUIC_PATCH_VERSION 0
/** /**

View file

@ -1,6 +1,6 @@
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ /* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
#ifndef LSXPACK_HEADER_H_v206 #ifndef LSXPACK_HEADER_H_v207
#define LSXPACK_HEADER_H_v206 #define LSXPACK_HEADER_H_v207
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -71,10 +71,10 @@ lsxpack_header_set_idx(lsxpack_header_t *hdr, int hpack_idx,
{ {
memset(hdr, 0, sizeof(*hdr)); memset(hdr, 0, sizeof(*hdr));
hdr->buf = (char *)val; hdr->buf = (char *)val;
hdr->hpack_index = hpack_idx; hdr->hpack_index = (uint8_t)hpack_idx;
assert(hpack_idx != 0); assert(hpack_idx != 0);
assert(val_len <= LSXPACK_MAX_STRLEN); assert(val_len <= LSXPACK_MAX_STRLEN);
hdr->val_len = val_len; hdr->val_len = (lsxpack_strlen_t)val_len;
} }
@ -84,11 +84,11 @@ lsxpack_header_set_qpack_idx(lsxpack_header_t *hdr, int qpack_idx,
{ {
memset(hdr, 0, sizeof(*hdr)); memset(hdr, 0, sizeof(*hdr));
hdr->buf = (char *)val; hdr->buf = (char *)val;
hdr->qpack_index = qpack_idx; hdr->qpack_index = (uint8_t)qpack_idx;
assert(qpack_idx != -1); assert(qpack_idx != -1);
hdr->flags = LSXPACK_QPACK_IDX; hdr->flags = LSXPACK_QPACK_IDX;
assert(val_len <= LSXPACK_MAX_STRLEN); assert(val_len <= LSXPACK_MAX_STRLEN);
hdr->val_len = val_len; hdr->val_len = (lsxpack_strlen_t)val_len;
} }
@ -99,13 +99,13 @@ lsxpack_header_set_offset(lsxpack_header_t *hdr, const char *buf,
{ {
memset(hdr, 0, sizeof(*hdr)); memset(hdr, 0, sizeof(*hdr));
hdr->buf = (char *)buf; hdr->buf = (char *)buf;
hdr->name_offset = name_offset; hdr->name_offset = (lsxpack_strlen_t)name_offset;
assert(name_len <= LSXPACK_MAX_STRLEN); assert(name_len <= LSXPACK_MAX_STRLEN);
hdr->name_len = name_len; hdr->name_len = (lsxpack_strlen_t)name_len;
assert(name_offset + name_len + 2 <= LSXPACK_MAX_STRLEN); assert(name_offset + name_len + 2 <= LSXPACK_MAX_STRLEN);
hdr->val_offset = name_offset + name_len + 2; hdr->val_offset = (lsxpack_strlen_t)(name_offset + name_len + 2);
assert(val_len <= LSXPACK_MAX_STRLEN); assert(val_len <= LSXPACK_MAX_STRLEN);
hdr->val_len = val_len; hdr->val_len = (lsxpack_strlen_t)val_len;
} }
@ -116,13 +116,13 @@ lsxpack_header_set_offset2(lsxpack_header_t *hdr, const char *buf,
{ {
memset(hdr, 0, sizeof(*hdr)); memset(hdr, 0, sizeof(*hdr));
hdr->buf = (char *)buf; hdr->buf = (char *)buf;
hdr->name_offset = name_offset; hdr->name_offset = (lsxpack_strlen_t)name_offset;
assert(name_len <= LSXPACK_MAX_STRLEN); assert(name_len <= LSXPACK_MAX_STRLEN);
hdr->name_len = name_len; hdr->name_len = (lsxpack_strlen_t)name_len;
assert(val_offset <= LSXPACK_MAX_STRLEN); assert(val_offset <= LSXPACK_MAX_STRLEN);
hdr->val_offset = val_offset; hdr->val_offset = (lsxpack_strlen_t)val_offset;
assert(val_len <= LSXPACK_MAX_STRLEN); assert(val_len <= LSXPACK_MAX_STRLEN);
hdr->val_len = val_len; hdr->val_len = (lsxpack_strlen_t)val_len;
} }
@ -133,11 +133,11 @@ lsxpack_header_prepare_decode(lsxpack_header_t *hdr,
memset(hdr, 0, sizeof(*hdr)); memset(hdr, 0, sizeof(*hdr));
hdr->buf = out; hdr->buf = out;
assert(offset <= LSXPACK_MAX_STRLEN); assert(offset <= LSXPACK_MAX_STRLEN);
hdr->name_offset = offset; hdr->name_offset = (lsxpack_strlen_t)offset;
if (len > LSXPACK_MAX_STRLEN) if (len > LSXPACK_MAX_STRLEN)
hdr->val_len = LSXPACK_MAX_STRLEN; hdr->val_len = LSXPACK_MAX_STRLEN;
else else
hdr->val_len = len; hdr->val_len = (lsxpack_strlen_t)len;
} }
@ -166,4 +166,4 @@ lsxpack_header_mark_val_changed(lsxpack_header_t *hdr)
} }
#endif #endif
#endif //LSXPACK_HEADER_H_v206 #endif //LSXPACK_HEADER_H_v207

@ -1 +1 @@
Subproject commit 5c1d58268b05dc47b7adf74dca5e677169710258 Subproject commit 60cae6e1564b01c2699c759b952523d5986671d1

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ /* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
/* Copyright (c) 2017 - 2023 LiteSpeed Technologies Inc. See LICENSE. */
/* /*
* lsquic_engine.c - QUIC engine * lsquic_engine.c - QUIC engine
*/ */

View file

@ -87,7 +87,7 @@
#define MAX_RETR_PACKETS_SINCE_LAST_ACK 2 #define MAX_RETR_PACKETS_SINCE_LAST_ACK 2
#define MAX_ANY_PACKETS_SINCE_LAST_ACK 20 #define MAX_ANY_PACKETS_SINCE_LAST_ACK 20
#define ACK_TIMEOUT (TP_DEF_MAX_ACK_DELAY * 1000) #define ACK_TIMEOUT (TP_DEF_MAX_ACK_DELAY * 1000)
#define INITIAL_CHAL_TIMEOUT 25000 #define INITIAL_CHAL_TIMEOUT 250000
/* Retire original CID after this much time has elapsed: */ /* Retire original CID after this much time has elapsed: */
#define RET_CID_TIMEOUT 2000000 #define RET_CID_TIMEOUT 2000000
@ -332,6 +332,10 @@ struct conn_path
COP_GOT_NONPROB = 1 << 2, COP_GOT_NONPROB = 1 << 2,
/* Spin bit is enabled on this path. */ /* Spin bit is enabled on this path. */
COP_SPIN_BIT = 1 << 3, COP_SPIN_BIT = 1 << 3,
/* Allow padding packet to 1200 bytes */
COP_ALLOW_MTU_PADDING = 1 << 4,
/* Verified that the path MTU is at least 1200 bytes */
COP_VALIDATED_MTU = 1 << 5,
} cop_flags; } cop_flags;
unsigned char cop_n_chals; unsigned char cop_n_chals;
unsigned char cop_cce_idx; unsigned char cop_cce_idx;
@ -1542,7 +1546,7 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
conn->ifc_flags |= IFC_IGNORE_INIT; conn->ifc_flags |= IFC_IGNORE_INIT;
conn->ifc_paths[0].cop_path = imc->imc_path; conn->ifc_paths[0].cop_path = imc->imc_path;
conn->ifc_paths[0].cop_flags = COP_VALIDATED|COP_INITIALIZED; conn->ifc_paths[0].cop_flags = COP_VALIDATED|COP_INITIALIZED|COP_ALLOW_MTU_PADDING;
conn->ifc_used_paths = 1 << 0; conn->ifc_used_paths = 1 << 0;
maybe_enable_spin(conn, &conn->ifc_paths[0]); maybe_enable_spin(conn, &conn->ifc_paths[0]);
if (imc->imc_flags & IMC_ADDR_VALIDATED) if (imc->imc_flags & IMC_ADDR_VALIDATED)
@ -4592,9 +4596,11 @@ generate_path_chal_frame (struct ietf_full_conn *conn, lsquic_time_t now,
if (copath->cop_n_chals >= sizeof(copath->cop_path_chals) if (copath->cop_n_chals >= sizeof(copath->cop_path_chals)
/ sizeof(copath->cop_path_chals[0])) / sizeof(copath->cop_path_chals[0]))
{ {
/* TODO: path failure? */ /* path failure? it is non-fatal, keep trying */
assert(0); memmove(&copath->cop_path_chals[0], &copath->cop_path_chals[1],
return; sizeof(copath->cop_path_chals) - sizeof(copath->cop_path_chals[0]));
copath->cop_n_chals = sizeof(copath->cop_path_chals)
/ sizeof(copath->cop_path_chals[0]) - 1;
} }
need = conn->ifc_conn.cn_pf->pf_path_chal_frame_size(); need = conn->ifc_conn.cn_pf->pf_path_chal_frame_size();
@ -4630,9 +4636,14 @@ generate_path_chal_frame (struct ietf_full_conn *conn, lsquic_time_t now,
packet_out->po_frame_types |= QUIC_FTBIT_PATH_CHALLENGE; packet_out->po_frame_types |= QUIC_FTBIT_PATH_CHALLENGE;
lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, w); lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, w);
packet_out->po_regen_sz += w; packet_out->po_regen_sz += w;
maybe_pad_packet(conn, packet_out);
conn->ifc_send_flags &= ~(SF_SEND_PATH_CHAL << path_id); conn->ifc_send_flags &= ~(SF_SEND_PATH_CHAL << path_id);
lsquic_alarmset_set(&conn->ifc_alset, AL_PATH_CHAL + path_id, /* Anti-amplification, only pad packet if allowed
* (confirmed path or incoming packet >= 400 bytes). */
if (copath->cop_flags & COP_ALLOW_MTU_PADDING)
maybe_pad_packet(conn, packet_out);
/* Only retry for confirmed path */
if (copath->cop_flags & COP_VALIDATED)
lsquic_alarmset_set(&conn->ifc_alset, AL_PATH_CHAL + path_id,
now + (INITIAL_CHAL_TIMEOUT << (copath->cop_n_chals - 1))); now + (INITIAL_CHAL_TIMEOUT << (copath->cop_n_chals - 1)));
} }
@ -5192,9 +5203,17 @@ process_path_response_frame (struct ietf_full_conn *conn,
return 0; return 0;
found: found:
path->cop_flags |= COP_VALIDATED; if (path->cop_flags & COP_ALLOW_MTU_PADDING)
conn->ifc_send_flags &= ~(SF_SEND_PATH_CHAL << path_id); {
lsquic_alarmset_unset(&conn->ifc_alset, AL_PATH_CHAL + path_id); path->cop_flags |= (COP_VALIDATED | COP_VALIDATED_MTU);
conn->ifc_send_flags &= ~(SF_SEND_PATH_CHAL << path_id);
lsquic_alarmset_unset(&conn->ifc_alset, AL_PATH_CHAL + path_id);
}
else
{
path->cop_flags |= (COP_VALIDATED | COP_ALLOW_MTU_PADDING);
conn->ifc_send_flags |= (SF_SEND_PATH_CHAL << path_id);
}
switch ((path_id != conn->ifc_cur_path_id) | switch ((path_id != conn->ifc_cur_path_id) |
(!!(path->cop_flags & COP_GOT_NONPROB) << 1)) (!!(path->cop_flags & COP_GOT_NONPROB) << 1))
{ {
@ -5522,7 +5541,8 @@ process_stop_sending_frame (struct ietf_full_conn *conn,
return 0; return 0;
} }
lsquic_stream_stop_sending_in(stream, error_code); lsquic_stream_stop_sending_in(stream, error_code);
lsquic_stream_call_on_new(stream); if (!(conn->ifc_flags & IFC_HTTP))
lsquic_stream_call_on_new(stream);
} }
return parsed_len; return parsed_len;
@ -6579,7 +6599,8 @@ process_ack_frequency_frame (struct ietf_full_conn *conn,
uint64_t seqno, pack_tol, upd_mad; uint64_t seqno, pack_tol, upd_mad;
int parsed_len, ignore; int parsed_len, ignore;
if (!(conn->ifc_flags & IFC_DELAYED_ACKS)) if (!conn->ifc_settings->es_delayed_acks
&& !(conn->ifc_flags & IFC_DELAYED_ACKS))
{ {
ABORT_QUIETLY(0, TEC_PROTOCOL_VIOLATION, ABORT_QUIETLY(0, TEC_PROTOCOL_VIOLATION,
"Received unexpected ACK_FREQUENCY frame (not negotiated)"); "Received unexpected ACK_FREQUENCY frame (not negotiated)");
@ -6857,7 +6878,11 @@ on_new_or_unconfirmed_path (struct ietf_full_conn *conn,
LSQ_DEBUGC("packet in DCID: %"CID_FMT"; changed: %d", LSQ_DEBUGC("packet in DCID: %"CID_FMT"; changed: %d",
CID_BITS(&packet_in->pi_dcid), dcid_changed); CID_BITS(&packet_in->pi_dcid), dcid_changed);
if (0 == init_new_path(conn, path, dcid_changed)) if (0 == init_new_path(conn, path, dcid_changed))
{
path->cop_flags |= COP_INITIALIZED; path->cop_flags |= COP_INITIALIZED;
if (packet_in->pi_data_sz >= IQUIC_MIN_INIT_PACKET_SZ / 3)
path->cop_flags |= COP_ALLOW_MTU_PADDING;
}
else else
return -1; return -1;

View file

@ -2346,8 +2346,8 @@ update_for_resending (lsquic_send_ctl_t *ctl, lsquic_packet_out_t *packet_out)
packno = send_ctl_next_packno(ctl); packno = send_ctl_next_packno(ctl);
packet_out->po_flags &= ~PO_SENT_SZ; packet_out->po_flags &= ~PO_SENT_SZ;
assert(packet_out->po_frame_types & ~BQUIC_FRAME_REGEN_MASK);
packet_out->po_frame_types &= ~BQUIC_FRAME_REGEN_MASK; packet_out->po_frame_types &= ~BQUIC_FRAME_REGEN_MASK;
assert(packet_out->po_frame_types);
packet_out->po_packno = packno; packet_out->po_packno = packno;
lsquic_packet_out_set_ecn(packet_out, ctl->sc_ecn); lsquic_packet_out_set_ecn(packet_out, ctl->sc_ecn);

View file

@ -2291,8 +2291,9 @@ stream_dispatch_write_events_loop (lsquic_stream_t *stream)
no_progress_count = 0; no_progress_count = 0;
stream->stream_flags |= STREAM_LAST_WRITE_OK; stream->stream_flags |= STREAM_LAST_WRITE_OK;
while ((stream->sm_qflags & SMQF_WANT_WRITE) while ((stream->sm_qflags & SMQF_WANT_WRITE)
&& (stream->stream_flags & STREAM_LAST_WRITE_OK) && (stream->stream_flags & STREAM_LAST_WRITE_OK)
&& stream_writeable(stream)) && !(stream->stream_flags & STREAM_ONCLOSE_DONE)
&& stream_writeable(stream))
{ {
progress = stream_progress(stream); progress = stream_progress(stream);
@ -2415,6 +2416,7 @@ lsquic_stream_dispatch_write_events (lsquic_stream_t *stream)
if (stream->sm_bflags & SMBF_RW_ONCE) if (stream->sm_bflags & SMBF_RW_ONCE)
{ {
if ((stream->sm_qflags & SMQF_WANT_WRITE) if ((stream->sm_qflags & SMQF_WANT_WRITE)
&& !(stream->stream_flags & STREAM_ONCLOSE_DONE)
&& stream_writeable(stream)) && stream_writeable(stream))
{ {
on_write = select_on_write(stream); on_write = select_on_write(stream);

@ -1 +1 @@
Subproject commit 14bec45020023db299b0a2c12a0c9ac90fbed49b Subproject commit a84a6b9f6d1e2dd5605c399fc2edcfeea8291258