From 2fb39e356740defae53a113adab90e46c2bb2ecc Mon Sep 17 00:00:00 2001 From: George Wang Date: Mon, 15 May 2023 00:27:34 -0400 Subject: [PATCH] Release 4.0.1 --- CHANGELOG | 6 +++++ docs/conf.py | 2 +- include/lsquic.h | 2 +- include/lsquic_types.h | 13 ++++----- src/liblsquic/ls-qpack | 2 +- src/liblsquic/lsquic_conn.c | 4 +-- src/liblsquic/lsquic_conn.h | 4 +-- src/liblsquic/lsquic_engine.c | 9 ++++--- src/liblsquic/lsquic_full_conn.c | 1 + src/liblsquic/lsquic_full_conn_ietf.c | 32 +++------------------- src/liblsquic/lsquic_mini_conn.c | 1 + src/liblsquic/lsquic_mini_conn_ietf.c | 39 ++++++++++++++++----------- src/liblsquic/lsquic_mini_conn_ietf.h | 4 +++ src/liblsquic/lsquic_send_ctl.c | 27 +++++++------------ src/liblsquic/lsquic_version.c | 7 +++++ src/lshpack | 2 +- tests/test_trapa.c | 2 +- 17 files changed, 74 insertions(+), 83 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 26de0ac..2af86fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +2023-05-14 + - 4.0.1 + - Fix send_ctl bug. + - Make logid consistent + - Reduce memory usage for storing CIDs. + 2023-03-14 - 4.0.0 - Add support for QUICv2 (RFC9369). diff --git a/docs/conf.py b/docs/conf.py index eb56dec..f68d528 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ author = u'LiteSpeed Technologies' # The short X.Y version version = u'4.0' # The full version, including alpha/beta/rc tags -release = u'4.0.0' +release = u'4.0.1' # -- General configuration --------------------------------------------------- diff --git a/include/lsquic.h b/include/lsquic.h index 5475bc0..257c311 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -27,7 +27,7 @@ extern "C" { #define LSQUIC_MAJOR_VERSION 4 #define LSQUIC_MINOR_VERSION 0 -#define LSQUIC_PATCH_VERSION 0 +#define LSQUIC_PATCH_VERSION 1 /** * Engine flags: diff --git a/include/lsquic_types.h b/include/lsquic_types.h index e76e4c9..30d1df1 100644 --- a/include/lsquic_types.h +++ b/include/lsquic_types.h @@ -18,18 +18,15 @@ */ typedef struct lsquic_cid { - uint_fast8_t len; - union { - uint8_t buf[MAX_CID_LEN]; - uint64_t id; - } u_cid; -#define idbuf u_cid.buf -} + uint8_t buf[MAX_CID_LEN]; +#define idbuf buf + uint_fast8_t len; +} __attribute__((__aligned__(8))) lsquic_cid_t; #define LSQUIC_CIDS_EQ(a, b) ((a)->len == 8 ? \ - (b)->len == 8 && (a)->u_cid.id == (b)->u_cid.id : \ + (b)->len == 8 && *(uint64_t *)((a)->buf) == *(uint64_t *)((b)->buf) : \ (a)->len == (b)->len && 0 == memcmp((a)->idbuf, (b)->idbuf, (a)->len)) /** Stream ID */ diff --git a/src/liblsquic/ls-qpack b/src/liblsquic/ls-qpack index bbd7070..ac3f635 160000 --- a/src/liblsquic/ls-qpack +++ b/src/liblsquic/ls-qpack @@ -1 +1 @@ -Subproject commit bbd707065f4547a1b5a25bbc1cf6c1963e86b8cf +Subproject commit ac3f63506eff136b4cd5d29e3c09492a540be75e diff --git a/src/liblsquic/lsquic_conn.c b/src/liblsquic/lsquic_conn.c index f76550d..3ee9bb4 100644 --- a/src/liblsquic/lsquic_conn.c +++ b/src/liblsquic/lsquic_conn.c @@ -274,9 +274,7 @@ lsquic_conn_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz) const lsquic_cid_t * lsquic_conn_log_cid (const struct lsquic_conn *lconn) { - if (lconn->cn_if && lconn->cn_if->ci_get_log_cid) - return lconn->cn_if->ci_get_log_cid(lconn); - return CN_SCID(lconn); + return &lconn->cn_logid; } diff --git a/src/liblsquic/lsquic_conn.h b/src/liblsquic/lsquic_conn.h index d0c4883..65d618f 100644 --- a/src/liblsquic/lsquic_conn.h +++ b/src/liblsquic/lsquic_conn.h @@ -255,9 +255,6 @@ struct conn_iface (*ci_record_addrs) (struct lsquic_conn *, void *peer_ctx, const struct sockaddr *local_sa, const struct sockaddr *peer_sa); - const lsquic_cid_t * - (*ci_get_log_cid) (const struct lsquic_conn *); - /* Optional method. Only used by the IETF client code. */ void (*ci_drop_crypto_streams) (struct lsquic_conn *); @@ -344,6 +341,7 @@ struct lsquic_conn const struct conn_iface *cn_if; const struct parse_funcs *cn_pf; struct attq_elem *cn_attq_elem; + lsquic_cid_t cn_logid; lsquic_time_t cn_last_sent; lsquic_time_t cn_last_ticked; struct conn_cid_elem *cn_cces; /* At least one is available */ diff --git a/src/liblsquic/lsquic_engine.c b/src/liblsquic/lsquic_engine.c index a5a217c..6222989 100644 --- a/src/liblsquic/lsquic_engine.c +++ b/src/liblsquic/lsquic_engine.c @@ -1152,7 +1152,7 @@ new_full_conn_server (lsquic_engine_t *engine, lsquic_conn_t *mini_conn, destroy_conn(engine, conn, now); return NULL; } - assert(!(conn->cn_flags & CONN_REF_FLAGS)); + assert(!(conn->cn_flags & (CONN_REF_FLAGS & ~LSCONN_TICKABLE))); conn->cn_flags |= LSCONN_HASHED; return conn; } @@ -1170,6 +1170,9 @@ promote_mini_conn (lsquic_engine_t *engine, lsquic_conn_t *mini_conn, EV_LOG_CONN_EVENT(lsquic_conn_log_cid( mini_conn ), "promote to full conn"); assert( mini_conn->cn_flags & LSCONN_MINI); + + lsquic_mini_conn_ietf_pre_promote((struct ietf_mini_conn *)mini_conn, now); + new_conn = new_full_conn_server(engine, mini_conn, now); if (new_conn) { @@ -1759,8 +1762,8 @@ process_packet_in (lsquic_engine_t *engine, lsquic_packet_in_t *packet_in, #endif QLOG_PACKET_RX(lsquic_conn_log_cid(conn), packet_in, packet_in_data, packet_in_size); lsquic_packet_in_put(&engine->pub.enp_mm, packet_in); - if ((conn->cn_flags & (LSCONN_MINI | LSCONN_HANDSHAKE_DONE)) - == (LSCONN_MINI | LSCONN_HANDSHAKE_DONE)) + if ((conn->cn_flags & (LSCONN_MINI | LSCONN_HANDSHAKE_DONE | LSCONN_IETF)) + == (LSCONN_MINI | LSCONN_HANDSHAKE_DONE | LSCONN_IETF)) { if (promote_mini_conn(engine, conn, lsquic_time_now()) == -1) conn->cn_flags |= LSCONN_PROMOTE_FAIL; diff --git a/src/liblsquic/lsquic_full_conn.c b/src/liblsquic/lsquic_full_conn.c index 7c82cd3..ec9b102 100644 --- a/src/liblsquic/lsquic_full_conn.c +++ b/src/liblsquic/lsquic_full_conn.c @@ -617,6 +617,7 @@ new_conn_common (lsquic_cid_t cid, struct lsquic_engine_public *enpub, conn->fc_conn.cn_cces = conn->fc_cces; conn->fc_conn.cn_cces_mask = 1; conn->fc_conn.cn_cid = cid; + conn->fc_conn.cn_logid = cid; conn->fc_flags = flags; conn->fc_enpub = enpub; conn->fc_pub.enpub = enpub; diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index b682c36..c73d761 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -81,7 +81,7 @@ #include "lsquic_qpack_exp.h" #define LSQUIC_LOGGER_MODULE LSQLM_CONN -#define LSQUIC_LOG_CONN_ID ietf_full_conn_ci_get_log_cid(&conn->ifc_conn) +#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(&conn->ifc_conn) #include "lsquic_logger.h" #define MAX_RETR_PACKETS_SINCE_LAST_ACK 2 @@ -577,9 +577,6 @@ ignore_hsk (struct ietf_full_conn *); static unsigned ietf_full_conn_ci_n_avail_streams (const struct lsquic_conn *); -static const lsquic_cid_t * -ietf_full_conn_ci_get_log_cid (const struct lsquic_conn *); - static void ietf_full_conn_ci_destroy (struct lsquic_conn *); @@ -1356,7 +1353,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub, / sizeof(conn->ifc_cces[0]); if (!ietf_full_conn_add_scid(conn, enpub, CCE_USED, now)) goto err1; - + conn->ifc_conn.cn_logid = *CN_SCID(&conn->ifc_conn); assert(versions); versions &= LSQUIC_IETF_VERSIONS; if (versions & (1 << LSQVER_I001)) @@ -1456,8 +1453,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub, lsquic_ver2str[conn->ifc_u.cli.ifcli_ver_neg.vn_ver]); conn->ifc_process_incoming_packet = process_incoming_packet_verneg; conn->ifc_created = now; - LSQ_DEBUG("logging using %s SCID", - LSQUIC_LOG_CONN_ID == CN_SCID(&conn->ifc_conn) ? "client" : "server"); + LSQ_DEBUG("logging using client SCID"); if (sess_resume && (params = conn->ifc_conn.cn_esf.i->esfi_get_peer_transport_params( conn->ifc_conn.cn_enc_session), params != NULL)) @@ -1537,7 +1533,7 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub, conn->ifc_scid_timestamp[i] = now; } ++conn->ifc_scid_seqno; - + conn->ifc_conn.cn_logid = mini_conn->cn_logid; /* Set the flags early so that correct CID is used for logging */ conn->ifc_conn.cn_flags |= LSCONN_IETF | LSCONN_SERVER; @@ -8804,25 +8800,6 @@ path_matches_local_sa (const struct network_path *path, } -static const lsquic_cid_t * -ietf_full_conn_ci_get_log_cid (const struct lsquic_conn *lconn) -{ - struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn; - - if (lconn->cn_flags & LSCONN_SERVER) - { - if (CUR_DCID(conn)->len) - return CUR_DCID(conn); - else - return CN_SCID(lconn); - } - if (CN_SCID(lconn)->len) - return CN_SCID(lconn); - else - return CUR_DCID(conn); -} - - static struct network_path * ietf_full_conn_ci_get_path (struct lsquic_conn *lconn, const struct sockaddr *sa) @@ -9025,7 +9002,6 @@ ietf_full_conn_ci_log_stats (struct lsquic_conn *lconn) .ci_drop_crypto_streams = ietf_full_conn_ci_drop_crypto_streams, \ .ci_early_data_failed = ietf_full_conn_ci_early_data_failed, \ .ci_get_engine = ietf_full_conn_ci_get_engine, \ - .ci_get_log_cid = ietf_full_conn_ci_get_log_cid, \ .ci_get_min_datagram_size= ietf_full_conn_ci_get_min_datagram_size, \ .ci_get_path = ietf_full_conn_ci_get_path, \ .ci_going_away = ietf_full_conn_ci_going_away, \ diff --git a/src/liblsquic/lsquic_mini_conn.c b/src/liblsquic/lsquic_mini_conn.c index d7aa161..c7c22ac 100644 --- a/src/liblsquic/lsquic_mini_conn.c +++ b/src/liblsquic/lsquic_mini_conn.c @@ -225,6 +225,7 @@ lsquic_mini_conn_new (struct lsquic_engine_public *enp, mc->mc_conn.cn_esf_c = select_esf_common_by_ver(version); mc->mc_conn.cn_esf.g = select_esf_gquic_by_ver(version); mc->mc_conn.cn_cid = packet_in->pi_conn_id; + mc->mc_conn.cn_logid = packet_in->pi_conn_id; mc->mc_conn.cn_flags = LSCONN_MINI | LSCONN_SERVER; mc->mc_conn.cn_if = conn_iface; LSQ_DEBUG("created mini connection object"); diff --git a/src/liblsquic/lsquic_mini_conn_ietf.c b/src/liblsquic/lsquic_mini_conn_ietf.c index 0c63815..427e83f 100644 --- a/src/liblsquic/lsquic_mini_conn_ietf.c +++ b/src/liblsquic/lsquic_mini_conn_ietf.c @@ -565,15 +565,19 @@ lsquic_mini_conn_ietf_new (struct lsquic_engine_public *enpub, conn->imc_cces[0].cce_flags = CCE_USED; conn->imc_conn.cn_cces_mask = 1; lsquic_scid_from_packet_in(packet_in, &conn->imc_path.np_dcid); - LSQ_DEBUGC("recv SCID from client %"CID_FMT, CID_BITS(&conn->imc_cces[0].cce_cid)); - LSQ_DEBUGC("recv DCID from client %"CID_FMT, CID_BITS(&conn->imc_path.np_dcid)); - /* Generate new SCID. Since is not the original SCID, it is given * a sequence number (0) and therefore can be retired by the client. */ enpub->enp_generate_scid(enpub->enp_gen_scid_ctx, &conn->imc_conn, &conn->imc_conn.cn_cces[1].cce_cid, enpub->enp_settings.es_scid_len); + if (conn->imc_path.np_dcid.len) + conn->imc_conn.cn_logid = conn->imc_path.np_dcid; + else + conn->imc_conn.cn_logid = conn->imc_conn.cn_cces[1].cce_cid; + + LSQ_DEBUGC("recv SCID from client %"CID_FMT, CID_BITS(&conn->imc_cces[0].cce_cid)); + LSQ_DEBUGC("recv DCID from client %"CID_FMT, CID_BITS(&conn->imc_path.np_dcid)); LSQ_DEBUGC("generated SCID %"CID_FMT" at index %u, switching to it", CID_BITS(&conn->imc_conn.cn_cces[1].cce_cid), 1); conn->imc_conn.cn_cces[1].cce_flags = CCE_SEQNO | CCE_USED; @@ -2084,6 +2088,22 @@ imico_generate_acks (struct ietf_mini_conn *conn, lsquic_time_t now) } +int +lsquic_mini_conn_ietf_pre_promote(struct ietf_mini_conn *conn, + lsquic_time_t now) +{ + if (conn->imc_flags & (IMC_QUEUED_ACK_INIT|IMC_QUEUED_ACK_HSK)) + { + if (0 != imico_generate_acks(conn, now)) + { + conn->imc_flags |= IMC_ERROR; + return -1; + } + } + return 0; +} + + static void imico_generate_conn_close (struct ietf_mini_conn *conn) { @@ -2367,18 +2387,6 @@ ietf_mini_conn_ci_get_path (struct lsquic_conn *lconn, } -static const lsquic_cid_t * -ietf_mini_conn_ci_get_log_cid (const struct lsquic_conn *lconn) -{ - struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; - - if (conn->imc_path.np_dcid.len) - return &conn->imc_path.np_dcid; - else - return CN_SCID(lconn); -} - - static unsigned char ietf_mini_conn_ci_record_addrs (struct lsquic_conn *lconn, void *peer_ctx, const struct sockaddr *local_sa, const struct sockaddr *peer_sa) @@ -2437,7 +2445,6 @@ static const struct conn_iface mini_conn_ietf_iface = { .ci_count_garbage = ietf_mini_conn_ci_count_garbage, .ci_destroy = ietf_mini_conn_ci_destroy, .ci_get_engine = ietf_mini_conn_ci_get_engine, - .ci_get_log_cid = ietf_mini_conn_ci_get_log_cid, .ci_get_path = ietf_mini_conn_ci_get_path, .ci_hsk_done = ietf_mini_conn_ci_hsk_done, .ci_internal_error = ietf_mini_conn_ci_internal_error, diff --git a/src/liblsquic/lsquic_mini_conn_ietf.h b/src/liblsquic/lsquic_mini_conn_ietf.h index 237599f..9308d06 100644 --- a/src/liblsquic/lsquic_mini_conn_ietf.h +++ b/src/liblsquic/lsquic_mini_conn_ietf.h @@ -164,4 +164,8 @@ lsquic_imico_rechist_first (void *rechist_ctx); const struct lsquic_packno_range * lsquic_imico_rechist_next (void *rechist_ctx); +int +lsquic_mini_conn_ietf_pre_promote(struct ietf_mini_conn *conn, + lsquic_time_t now); + #endif diff --git a/src/liblsquic/lsquic_send_ctl.c b/src/liblsquic/lsquic_send_ctl.c index 19def4a..84fa7c5 100644 --- a/src/liblsquic/lsquic_send_ctl.c +++ b/src/liblsquic/lsquic_send_ctl.c @@ -297,7 +297,8 @@ retx_alarm_rings (enum alarm_id al_id, void *ctx, lsquic_time_t expiry, lsquic_t send_ctl_expire(ctl, pns, EXFI_LAST); break; case RETX_MODE_RTO: - if ( now - ctl->sc_last_rto_time >= calculate_packet_rto(ctl)) + if ((ctl->sc_flags & SC_1RTT_ACKED) + || now - ctl->sc_last_rto_time >= calculate_packet_rto(ctl)) { ctl->sc_last_rto_time = now; ++ctl->sc_n_consec_rtos; @@ -923,7 +924,8 @@ static void send_ctl_acked_loss_chain (struct lsquic_send_ctl *ctl, struct lsquic_packet_out *const packet_out, struct lsquic_packet_out **next, - lsquic_packno_t largest_acked) + lsquic_packno_t largest_acked, + signed char *do_rtt) { struct lsquic_packet_out *chain_cur, *chain_next; unsigned count; @@ -932,13 +934,8 @@ send_ctl_acked_loss_chain (struct lsquic_send_ctl *ctl, chain_cur = chain_next) { chain_next = chain_cur->po_loss_chain; - if (chain_cur->po_packno > packet_out->po_packno - && chain_cur->po_packno <= largest_acked - && (chain_cur->po_flags & PO_LOST) == 0) - { - chain_cur->po_flags |= PO_ACKED_LOSS_CHAIN; - continue; - } + if (chain_cur->po_packno == largest_acked) + *do_rtt = 1; send_ctl_process_loss_chain_pkt(ctl, chain_cur, next); ++count; } @@ -1393,15 +1390,10 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl, do_rtt |= packet_out->po_packno == largest_acked(acki); ctl->sc_ci->cci_ack(CGP(ctl), packet_out, packet_sz, now, app_limited); - if (!(packet_out->po_flags & PO_ACKED_LOSS_CHAIN)) - send_ctl_acked_loss_chain(ctl, packet_out, &next, - largest_acked(acki)); + send_ctl_acked_loss_chain(ctl, packet_out, &next, + largest_acked(acki), &do_rtt); send_ctl_destroy_packet(ctl, packet_out); } - else if (packet_out->po_flags & PO_ACKED_LOSS_CHAIN) - { - send_ctl_process_loss_chain_pkt(ctl, packet_out, &next); - } packet_out = next; } while (packet_out && packet_out->po_packno <= largest_acked(acki)); @@ -1419,7 +1411,8 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl, losses_detected = send_ctl_detect_losses(ctl, pns, ack_recv_time); if (send_ctl_first_unacked_retx_packet(ctl, pns)) { - if (!lsquic_alarmset_is_set(ctl->sc_alset, pns) && losses_detected) + if ((ctl->sc_flags & SC_1RTT_ACKED) + || (!lsquic_alarmset_is_set(ctl->sc_alset, pns) && losses_detected)) set_retx_alarm(ctl, pns, now); } else diff --git a/src/liblsquic/lsquic_version.c b/src/liblsquic/lsquic_version.c index 7120d65..f27039f 100644 --- a/src/liblsquic/lsquic_version.c +++ b/src/liblsquic/lsquic_version.c @@ -72,6 +72,13 @@ lsquic_tag2ver_fast (const unsigned char *tag) else if (*(tag + 3) == 0x00) return LSQVER_VERNEG; } + else if (ch == 0xff && *(tag + 1) == 0 && *(tag + 2) == 0) + { + if (*(tag + 3) == 0x1D) + return LSQVER_ID29; + else if (*(tag + 3) == 0x1B) + return LSQVER_ID27; + } else if ((ch & 0xf) == 0xa && (*(tag + 1) & 0xf) == 0xa && (*(tag + 2) & 0xf) == 0xa && (*(tag + 3) & 0xf) == 0xa) return LSQVER_RESVED; diff --git a/src/lshpack b/src/lshpack index a84a6b9..22ec69c 160000 --- a/src/lshpack +++ b/src/lshpack @@ -1 +1 @@ -Subproject commit a84a6b9f6d1e2dd5605c399fc2edcfeea8291258 +Subproject commit 22ec69cff73ec10ecc13c96a387017c89773ecd3 diff --git a/tests/test_trapa.c b/tests/test_trapa.c index a0e7e89..5cb5898 100644 --- a/tests/test_trapa.c +++ b/tests/test_trapa.c @@ -72,7 +72,7 @@ static const struct trapa_test tests[] = .tp_max_idle_timeout = 10 * 1000, .tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY, .tp_active_connection_id_limit = 7, - .tp_initial_source_cid = { .len = 8, .u_cid.id = 0x0807060504030201ull, }, + .tp_initial_source_cid = { .len = 8, .buf = "\x01\x02\x03\x04\x05\x06\x07\x08", }, }, .is_server = 0, .enc_len = 36,