summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2023-07-18 17:12:04 +0200
committerMatt Caswell <matt@openssl.org>2023-07-31 15:03:25 +0200
commit03b3859501b69d48c8710b6a0754842c7166a7c1 (patch)
tree8219bf53cd9635e389ee2402ac89098b84d7d721
parentUpdate GOST engine commit to deal with test failure (diff)
downloadopenssl-03b3859501b69d48c8710b6a0754842c7166a7c1.tar.xz
openssl-03b3859501b69d48c8710b6a0754842c7166a7c1.zip
QUIC CHANNEL: Allow ticking to be inhibited for testing purposes
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21484)
-rw-r--r--include/internal/quic_channel.h3
-rw-r--r--ssl/quic/quic_channel.c94
-rw-r--r--ssl/quic/quic_channel_local.h3
3 files changed, 59 insertions, 41 deletions
diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h
index bd9f45c68a..03aeab949b 100644
--- a/include/internal/quic_channel.h
+++ b/include/internal/quic_channel.h
@@ -353,6 +353,9 @@ int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch);
/* Force transmission of an ACK-eliciting packet. */
int ossl_quic_channel_ping(QUIC_CHANNEL *ch);
+/* For testing use. While enabled, ticking is not performed. */
+void ossl_quic_channel_set_inhibit_tick(QUIC_CHANNEL *ch, int inhibit);
+
# endif
#endif
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c
index 1e6a29a706..b516746b58 100644
--- a/ssl/quic/quic_channel.c
+++ b/ssl/quic/quic_channel.c
@@ -1631,69 +1631,76 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags)
}
}
- /* Handle RXKU timeouts. */
- ch_rxku_tick(ch);
+ if (!ch->inhibit_tick) {
+ /* Handle RXKU timeouts. */
+ ch_rxku_tick(ch);
- /* Handle any incoming data from network. */
- ch_rx_pre(ch);
+ /* Handle any incoming data from network. */
+ ch_rx_pre(ch);
- do {
- /* Process queued incoming packets. */
- ch_rx(ch);
+ do {
+ /* Process queued incoming packets. */
+ ch_rx(ch);
- /*
- * Allow the handshake layer to check for any new incoming data and generate
- * new outgoing data.
- */
- ch->have_new_rx_secret = 0;
- if (!channel_only)
- ossl_quic_tls_tick(ch->qtls);
+ /*
+ * Allow the handshake layer to check for any new incoming data and
+ * generate new outgoing data.
+ */
+ ch->have_new_rx_secret = 0;
+ if (!channel_only)
+ ossl_quic_tls_tick(ch->qtls);
- /*
- * If the handshake layer gave us a new secret, we need to do RX again
- * because packets that were not previously processable and were
- * deferred might now be processable.
- *
- * TODO(QUIC): Consider handling this in the yield_secret callback.
- */
- } while (ch->have_new_rx_secret);
+ /*
+ * If the handshake layer gave us a new secret, we need to do RX
+ * again because packets that were not previously processable and
+ * were deferred might now be processable.
+ *
+ * TODO(QUIC): Consider handling this in the yield_secret callback.
+ */
+ } while (ch->have_new_rx_secret);
+ }
/*
- * Handle any timer events which are due to fire; namely, the loss detection
- * deadline and the idle timeout.
+ * Handle any timer events which are due to fire; namely, the loss
+ * detection deadline and the idle timeout.
*
- * ACKM ACK generation deadline is polled by TXP, so we don't need to handle
- * it here.
+ * ACKM ACK generation deadline is polled by TXP, so we don't need to
+ * handle it here.
*/
now = get_time(ch);
if (ossl_time_compare(now, ch->idle_deadline) >= 0) {
/*
- * Idle timeout differs from normal protocol violation because we do not
- * send a CONN_CLOSE frame; go straight to TERMINATED.
+ * Idle timeout differs from normal protocol violation because we do
+ * not send a CONN_CLOSE frame; go straight to TERMINATED.
*/
- ch_on_idle_timeout(ch);
+ if (!ch->inhibit_tick)
+ ch_on_idle_timeout(ch);
+
res->net_read_desired = 0;
res->net_write_desired = 0;
res->tick_deadline = ossl_time_infinite();
return;
}
- deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm);
- if (!ossl_time_is_zero(deadline) && ossl_time_compare(now, deadline) >= 0)
- ossl_ackm_on_timeout(ch->ackm);
+ if (!ch->inhibit_tick) {
+ deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm);
+ if (!ossl_time_is_zero(deadline)
+ && ossl_time_compare(now, deadline) >= 0)
+ ossl_ackm_on_timeout(ch->ackm);
- /* If a ping is due, inform TXP. */
- if (ossl_time_compare(now, ch->ping_deadline) >= 0) {
- int pn_space = ossl_quic_enc_level_to_pn_space(ch->tx_enc_level);
+ /* If a ping is due, inform TXP. */
+ if (ossl_time_compare(now, ch->ping_deadline) >= 0) {
+ int pn_space = ossl_quic_enc_level_to_pn_space(ch->tx_enc_level);
- ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, pn_space);
- }
+ ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, pn_space);
+ }
- /* Write any data to the network due to be sent. */
- ch_tx(ch);
+ /* Write any data to the network due to be sent. */
+ ch_tx(ch);
- /* Do stream GC. */
- ossl_quic_stream_map_gc(&ch->qsm);
+ /* Do stream GC. */
+ ossl_quic_stream_map_gc(&ch->qsm);
+ }
/* Determine the time at which we should next be ticked. */
res->tick_deadline = ch_determine_next_tick_deadline(ch);
@@ -3152,3 +3159,8 @@ int ossl_quic_channel_ping(QUIC_CHANNEL *ch)
return 1;
}
+
+void ossl_quic_channel_set_inhibit_tick(QUIC_CHANNEL *ch, int inhibit)
+{
+ ch->inhibit_tick = (inhibit != 0);
+}
diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h
index 8cc903506d..8e7d78855e 100644
--- a/ssl/quic/quic_channel_local.h
+++ b/ssl/quic/quic_channel_local.h
@@ -404,6 +404,9 @@ struct quic_channel_st {
/* Permanent net error encountered */
unsigned int net_error : 1;
+ /* Inhibit tick for testing purposes? */
+ unsigned int inhibit_tick : 1;
+
/* Saved error stack in case permanent error was encountered */
ERR_STATE *err_state;
};