summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2023-05-23 12:23:06 +0100
committerPauli <pauli@openssl.org>2023-06-16 09:26:28 +1000
commit37ba2bc72281c196534e265c34be94beb760393e (patch)
tree2363259b6edf6fdce2d146691d971716f77d9be9
parent16f3b542f89dbdd6029400c740a55d49d4af8e53 (diff)
QUIC CHANNEL: Optimise key update using ACKs
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21029)
-rw-r--r--include/internal/quic_txp.h7
-rw-r--r--ssl/quic/quic_channel.c17
-rw-r--r--ssl/quic/quic_txp.c6
3 files changed, 30 insertions, 0 deletions
diff --git a/include/internal/quic_txp.h b/include/internal/quic_txp.h
index 7238fae1aa..2a503770bc 100644
--- a/include/internal/quic_txp.h
+++ b/include/internal/quic_txp.h
@@ -163,6 +163,13 @@ void ossl_quic_tx_packetiser_schedule_ack_eliciting(OSSL_QUIC_TX_PACKETISER *txp
uint32_t pn_space);
/*
+ * Asks the TXP to ensure an ACK is put in the next packet in the given PN
+ * space.
+ */
+void ossl_quic_tx_packetiser_schedule_ack(OSSL_QUIC_TX_PACKETISER *txp,
+ uint32_t pn_space);
+
+/*
* Schedules a connection close. *f and f->reason are copied. This operation is
* irreversible and causes all further packets generated by the TXP to contain a
* CONNECTION_CLOSE frame. This function fails if it has already been called
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c
index c4dfa58bc1..efc9fd7f4a 100644
--- a/ssl/quic/quic_channel.c
+++ b/ssl/quic/quic_channel.c
@@ -701,6 +701,23 @@ static void rxku_detected(QUIC_PN pn, void *arg)
if (decision == DECISION_SOLICITED_TXKU)
/* NOT gated by usual txku_allowed() */
ch_trigger_txku(ch);
+
+ /*
+ * Ordinarily, we only generate ACK when some ACK-eliciting frame has been
+ * received. In some cases, this may not occur for a long time, for example
+ * if transmission of application data is going in only one direction and
+ * nothing else is happening with the connection. However, since the peer
+ * cannot initiate a subsequent (spontaneous) TXKU until its prior
+ * (spontaneous or solicited) TXKU has completed - meaning that that prior
+ * TXKU's trigger packet (or subsequent packet) has been acknowledged, this
+ * can lead to very long times before a TXKU is considered 'completed'.
+ * Optimise this by forcing ACK generation after triggering TXKU.
+ * (Basically, we consider a RXKU event something that is 'ACK-eliciting',
+ * which it more or less should be; it is necessarily separate from ordinary
+ * processing of ACK-eliciting frames as key update is not indicated via a
+ * frame.)
+ */
+ ossl_quic_tx_packetiser_schedule_ack(ch->txp, QUIC_PN_SPACE_APP);
}
/* Called per tick to handle RXKU timer events. */
diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c
index 1acf42104a..f471237e2a 100644
--- a/ssl/quic/quic_txp.c
+++ b/ssl/quic/quic_txp.c
@@ -519,6 +519,12 @@ void ossl_quic_tx_packetiser_schedule_ack_eliciting(OSSL_QUIC_TX_PACKETISER *txp
txp->force_ack_eliciting |= (1UL << pn_space);
}
+void ossl_quic_tx_packetiser_schedule_ack(OSSL_QUIC_TX_PACKETISER *txp,
+ uint32_t pn_space)
+{
+ txp->want_ack |= (1UL << pn_space);
+}
+
#define TXP_ERR_INTERNAL 0 /* Internal (e.g. alloc) error */
#define TXP_ERR_SUCCESS 1 /* Success */
#define TXP_ERR_SPACE 2 /* Not enough room for another packet */