From 8f9c9213a1ba034de3140a0d0c0c3b1e46afe457 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Tue, 23 May 2023 12:23:06 +0100 Subject: [PATCH] QUIC TXP: Allow callbacks on ACK transmission Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21029) --- include/internal/quic_txp.h | 11 +++++++++++ ssl/quic/quic_txp.c | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/include/internal/quic_txp.h b/include/internal/quic_txp.h index 31578bb1788aa..7238fae1aa0c8 100644 --- a/include/internal/quic_txp.h +++ b/include/internal/quic_txp.h @@ -184,6 +184,17 @@ void ossl_quic_tx_packetiser_set_msg_callback_arg(OSSL_QUIC_TX_PACKETISER *txp, */ QUIC_PN ossl_quic_tx_packetiser_get_next_pn(OSSL_QUIC_TX_PACKETISER *txp, uint32_t pn_space); + +/* + * Sets a callback which is called whenever TXP sends an ACK frame. The callee + * must not modify the ACK frame data. Can be used to snoop on PNs being ACKed. + */ +void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp, + void (*cb)(const OSSL_QUIC_FRAME_ACK *ack, + uint32_t pn_space, + void *arg), + void *cb_arg); + # endif #endif diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c index 08f3d7f7b69ef..7c5e4295f3812 100644 --- a/ssl/quic/quic_txp.c +++ b/ssl/quic/quic_txp.c @@ -75,6 +75,11 @@ struct ossl_quic_tx_packetiser_st { void *msg_callback_arg; SSL *msg_callback_ssl; + /* Callbacks. */ + void (*ack_tx_cb)(const OSSL_QUIC_FRAME_ACK *ack, + uint32_t pn_space, + void *arg); + void *ack_tx_cb_arg; }; /* @@ -474,6 +479,16 @@ int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp, return 1; } +void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp, + void (*cb)(const OSSL_QUIC_FRAME_ACK *ack, + uint32_t pn_space, + void *arg), + void *cb_arg) +{ + txp->ack_tx_cb = cb; + txp->ack_tx_cb_arg = cb_arg; +} + int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level) { @@ -1247,6 +1262,9 @@ static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp, if (ack->num_ack_ranges > 0) tpkt->ackm_pkt.largest_acked = ack->ack_ranges[0].end; + + if (txp->ack_tx_cb != NULL) + txp->ack_tx_cb(&ack2, pn_space, txp->ack_tx_cb_arg); } else { tx_helper_rollback(h); }