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
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. */
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 */