From 48365d5741410d7ed95fdeb01f0d7b2e7b85bf21 Mon Sep 17 00:00:00 2001 From: George Wang Date: Wed, 4 Jan 2023 15:21:42 -0500 Subject: [PATCH] Release 3.3.0 --- CHANGELOG | 13 +++++-- LICENSE | 2 +- README.md | 3 +- docs/conf.py | 6 ++-- include/lsquic.h | 4 ++- include/lsxpack_header.h | 34 +++++++++---------- src/liblsquic/ls-qpack | 2 +- src/liblsquic/lsquic_engine.c | 1 + src/liblsquic/lsquic_full_conn_ietf.c | 49 ++++++++++++++++++++------- src/liblsquic/lsquic_send_ctl.c | 2 +- src/liblsquic/lsquic_stream.c | 6 ++-- src/lshpack | 2 +- 12 files changed, 82 insertions(+), 42 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9bb1804..8059826 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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 - 3.2.0 - Update ls-qpack to 2.5.0 to address a decoder bug - Assertion failure if poison packet was acked - Fix packet_in pool memory leak - 2022-08-16 - 3.1.2 - Update ls-qpack to 2.4.0 to address a use-after-free bug @@ -14,7 +24,6 @@ - Fix IPv6 MTU detection - Fix wrong size used in packet regeneration. - 2022-05-13 - 3.1.1 - Fix memory leak in processing stream frames (isse #368) diff --git a/LICENSE b/LICENSE index 8a83a86..690173b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ 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 of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 18018a7..ee02e01 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,9 @@ You may need to install pre-requisites like zlib and libevent. 2. Use specific BoringSSL version ``` -git checkout a9670a8b476470e6f874fef3554e8059683e1413 +git checkout 31bad2514d21f6207f3925ba56754611c462a873 ``` +Or, just try the latest master branch. 3. Compile the library diff --git a/docs/conf.py b/docs/conf.py index b6e5942..f46c5e4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,13 +20,13 @@ # -- Project information ----------------------------------------------------- project = u'lsquic' -copyright = u'2022, LiteSpeed Technologies' +copyright = u'2023, LiteSpeed Technologies' author = u'LiteSpeed Technologies' # The short X.Y version -version = u'3.2' +version = u'3.3' # The full version, including alpha/beta/rc tags -release = u'3.2.0' +release = u'3.3.0' # -- General configuration --------------------------------------------------- diff --git a/include/lsquic.h b/include/lsquic.h index 0f772eb..e4e02c3 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -1,4 +1,6 @@ /* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ +/* Copyright (c) 2017 - 2023 LiteSpeed Technologies Inc. See LICENSE. */ + #ifndef __LSQUIC_H__ #define __LSQUIC_H__ @@ -24,7 +26,7 @@ extern "C" { #endif #define LSQUIC_MAJOR_VERSION 3 -#define LSQUIC_MINOR_VERSION 2 +#define LSQUIC_MINOR_VERSION 3 #define LSQUIC_PATCH_VERSION 0 /** diff --git a/include/lsxpack_header.h b/include/lsxpack_header.h index 9c05c75..d34c3ab 100644 --- a/include/lsxpack_header.h +++ b/include/lsxpack_header.h @@ -1,6 +1,6 @@ /* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ -#ifndef LSXPACK_HEADER_H_v206 -#define LSXPACK_HEADER_H_v206 +#ifndef LSXPACK_HEADER_H_v207 +#define LSXPACK_HEADER_H_v207 #ifdef __cplusplus extern "C" { @@ -71,10 +71,10 @@ lsxpack_header_set_idx(lsxpack_header_t *hdr, int hpack_idx, { memset(hdr, 0, sizeof(*hdr)); hdr->buf = (char *)val; - hdr->hpack_index = hpack_idx; + hdr->hpack_index = (uint8_t)hpack_idx; assert(hpack_idx != 0); 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)); hdr->buf = (char *)val; - hdr->qpack_index = qpack_idx; + hdr->qpack_index = (uint8_t)qpack_idx; assert(qpack_idx != -1); hdr->flags = LSXPACK_QPACK_IDX; 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)); hdr->buf = (char *)buf; - hdr->name_offset = name_offset; + hdr->name_offset = (lsxpack_strlen_t)name_offset; 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); - 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); - 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)); hdr->buf = (char *)buf; - hdr->name_offset = name_offset; + hdr->name_offset = (lsxpack_strlen_t)name_offset; 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); - hdr->val_offset = val_offset; + hdr->val_offset = (lsxpack_strlen_t)val_offset; 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)); hdr->buf = out; assert(offset <= LSXPACK_MAX_STRLEN); - hdr->name_offset = offset; + hdr->name_offset = (lsxpack_strlen_t)offset; if (len > LSXPACK_MAX_STRLEN) hdr->val_len = LSXPACK_MAX_STRLEN; 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 //LSXPACK_HEADER_H_v206 +#endif //LSXPACK_HEADER_H_v207 diff --git a/src/liblsquic/ls-qpack b/src/liblsquic/ls-qpack index 5c1d582..60cae6e 160000 --- a/src/liblsquic/ls-qpack +++ b/src/liblsquic/ls-qpack @@ -1 +1 @@ -Subproject commit 5c1d58268b05dc47b7adf74dca5e677169710258 +Subproject commit 60cae6e1564b01c2699c759b952523d5986671d1 diff --git a/src/liblsquic/lsquic_engine.c b/src/liblsquic/lsquic_engine.c index 7161f20..3e6823d 100644 --- a/src/liblsquic/lsquic_engine.c +++ b/src/liblsquic/lsquic_engine.c @@ -1,4 +1,5 @@ /* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ +/* Copyright (c) 2017 - 2023 LiteSpeed Technologies Inc. See LICENSE. */ /* * lsquic_engine.c - QUIC engine */ diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index db09df0..bc8e48d 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -87,7 +87,7 @@ #define MAX_RETR_PACKETS_SINCE_LAST_ACK 2 #define MAX_ANY_PACKETS_SINCE_LAST_ACK 20 #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: */ #define RET_CID_TIMEOUT 2000000 @@ -332,6 +332,10 @@ struct conn_path COP_GOT_NONPROB = 1 << 2, /* Spin bit is enabled on this path. */ 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; unsigned char cop_n_chals; 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_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; maybe_enable_spin(conn, &conn->ifc_paths[0]); 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) / sizeof(copath->cop_path_chals[0])) { - /* TODO: path failure? */ - assert(0); - return; + /* path failure? it is non-fatal, keep trying */ + memmove(&copath->cop_path_chals[0], &copath->cop_path_chals[1], + 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(); @@ -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; lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, w); packet_out->po_regen_sz += w; - maybe_pad_packet(conn, packet_out); 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))); } @@ -5192,9 +5203,17 @@ process_path_response_frame (struct ietf_full_conn *conn, return 0; found: - path->cop_flags |= COP_VALIDATED; - conn->ifc_send_flags &= ~(SF_SEND_PATH_CHAL << path_id); - lsquic_alarmset_unset(&conn->ifc_alset, AL_PATH_CHAL + path_id); + if (path->cop_flags & COP_ALLOW_MTU_PADDING) + { + 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) | (!!(path->cop_flags & COP_GOT_NONPROB) << 1)) { @@ -5522,7 +5541,8 @@ process_stop_sending_frame (struct ietf_full_conn *conn, return 0; } 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; @@ -6579,7 +6599,8 @@ process_ack_frequency_frame (struct ietf_full_conn *conn, uint64_t seqno, pack_tol, upd_mad; 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, "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", CID_BITS(&packet_in->pi_dcid), dcid_changed); if (0 == init_new_path(conn, path, dcid_changed)) + { 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 return -1; diff --git a/src/liblsquic/lsquic_send_ctl.c b/src/liblsquic/lsquic_send_ctl.c index 7d2861d..d6ce861 100644 --- a/src/liblsquic/lsquic_send_ctl.c +++ b/src/liblsquic/lsquic_send_ctl.c @@ -2346,8 +2346,8 @@ update_for_resending (lsquic_send_ctl_t *ctl, lsquic_packet_out_t *packet_out) packno = send_ctl_next_packno(ctl); 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; - assert(packet_out->po_frame_types); packet_out->po_packno = packno; lsquic_packet_out_set_ecn(packet_out, ctl->sc_ecn); diff --git a/src/liblsquic/lsquic_stream.c b/src/liblsquic/lsquic_stream.c index fb68a75..7502f5e 100644 --- a/src/liblsquic/lsquic_stream.c +++ b/src/liblsquic/lsquic_stream.c @@ -2291,8 +2291,9 @@ stream_dispatch_write_events_loop (lsquic_stream_t *stream) no_progress_count = 0; stream->stream_flags |= STREAM_LAST_WRITE_OK; while ((stream->sm_qflags & SMQF_WANT_WRITE) - && (stream->stream_flags & STREAM_LAST_WRITE_OK) - && stream_writeable(stream)) + && (stream->stream_flags & STREAM_LAST_WRITE_OK) + && !(stream->stream_flags & STREAM_ONCLOSE_DONE) + && stream_writeable(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_qflags & SMQF_WANT_WRITE) + && !(stream->stream_flags & STREAM_ONCLOSE_DONE) && stream_writeable(stream)) { on_write = select_on_write(stream); diff --git a/src/lshpack b/src/lshpack index 14bec45..a84a6b9 160000 --- a/src/lshpack +++ b/src/lshpack @@ -1 +1 @@ -Subproject commit 14bec45020023db299b0a2c12a0c9ac90fbed49b +Subproject commit a84a6b9f6d1e2dd5605c399fc2edcfeea8291258