summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2023-08-17 15:35:15 +0100
committerTomas Mraz <tomas@openssl.org>2023-08-25 08:42:39 +0200
commitaa433014bb36bfff0af17c0eb9d25b6fb2d7d068 (patch)
tree11635db7643e72037b309e6e2406659700e12096 /ssl
parente2972982c64f3f1ac10b3ebe1086d99ec67631bd (diff)
Keep sending datagrams while we have data to send
If we've got more data to send than will fit in a single datagram we should keep generating those datagrams until we've sent it all. Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21798)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/quic/quic_channel.c95
1 files changed, 50 insertions, 45 deletions
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c
index 9fca47bb31..5cee9f7532 100644
--- a/ssl/quic/quic_channel.c
+++ b/ssl/quic/quic_channel.c
@@ -2406,57 +2406,62 @@ static int ch_tx(QUIC_CHANNEL *ch)
ch->rxku_pending_confirm_done = 0;
- /*
- * Send a packet, if we need to. Best effort. The TXP consults the CC and
- * applies any limitations imposed by it, so we don't need to do it here.
- *
- * Best effort. In particular if TXP fails for some reason we should still
- * flush any queued packets which we already generated.
- */
- res = ossl_quic_tx_packetiser_generate(ch->txp, &status);
- if (status.sent_pkt > 0) {
- ch->have_sent_any_pkt = 1; /* Packet was sent */
-
+ /* Loop until we stop generating packets to send */
+ do {
/*
- * RFC 9000 s. 10.1. 'An endpoint also restarts its idle timer when
- * sending an ack-eliciting packet if no other ack-eliciting packets
- * have been sent since last receiving and processing a packet.'
- */
- if (status.sent_ack_eliciting && !ch->have_sent_ack_eliciting_since_rx) {
- ch_update_idle(ch);
- ch->have_sent_ack_eliciting_since_rx = 1;
- }
+ * Send packet, if we need to. Best effort. The TXP consults the CC and
+ * applies any limitations imposed by it, so we don't need to do it here.
+ *
+ * Best effort. In particular if TXP fails for some reason we should
+ * still flush any queued packets which we already generated.
+ */
+ res = ossl_quic_tx_packetiser_generate(ch->txp, &status);
+ if (status.sent_pkt > 0) {
+ ch->have_sent_any_pkt = 1; /* Packet(s) were sent */
- if (!ch->is_server && status.sent_handshake)
/*
- * RFC 9001 s. 4.9.1: A client MUST discard Initial keys when it
- * first sends a Handshake packet.
- */
- ch_discard_el(ch, QUIC_ENC_LEVEL_INITIAL);
+ * RFC 9000 s. 10.1. 'An endpoint also restarts its idle timer when
+ * sending an ack-eliciting packet if no other ack-eliciting packets
+ * have been sent since last receiving and processing a packet.'
+ */
+ if (status.sent_ack_eliciting
+ && !ch->have_sent_ack_eliciting_since_rx) {
+ ch_update_idle(ch);
+ ch->have_sent_ack_eliciting_since_rx = 1;
+ }
- if (ch->rxku_pending_confirm_done)
- ch->rxku_pending_confirm = 0;
+ if (!ch->is_server && status.sent_handshake)
+ /*
+ * RFC 9001 s. 4.9.1: A client MUST discard Initial keys when it
+ * first sends a Handshake packet.
+ */
+ ch_discard_el(ch, QUIC_ENC_LEVEL_INITIAL);
- ch_update_ping_deadline(ch);
- }
+ if (ch->rxku_pending_confirm_done)
+ ch->rxku_pending_confirm = 0;
- if (!res) {
- /*
- * Internal failure (e.g. allocation, assertion).
- *
- * One case where TXP can fail is if we reach a TX PN of 2**62 - 1. As
- * per RFC 9000 s. 12.3, if this happens we MUST close the connection
- * without sending a CONNECTION_CLOSE frame. This is actually handled as
- * an emergent consequence of our design, as the TX packetiser will
- * never transmit another packet when the TX PN reaches the limit.
- *
- * Calling the below function terminates the connection; its attempt to
- * schedule a CONNECTION_CLOSE frame will not actually cause a packet to
- * be transmitted for this reason.
- */
- ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0,
- "internal error (txp generate)");
- }
+ ch_update_ping_deadline(ch);
+ }
+
+ if (!res) {
+ /*
+ * One case where TXP can fail is if we reach a TX PN of 2**62 - 1.
+ * As per RFC 9000 s. 12.3, if this happens we MUST close the
+ * connection without sending a CONNECTION_CLOSE frame. This is
+ * actually handled as an emergent consequence of our design, as the
+ * TX packetiser will never transmit another packet when the TX PN
+ * reaches the limit.
+ *
+ * Calling the below function terminates the connection; its attempt
+ * to schedule a CONNECTION_CLOSE frame will not actually cause a
+ * packet to be transmitted for this reason.
+ */
+ ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR,
+ 0,
+ "internal error (txp generate)");
+ break;
+ }
+ } while (status.sent_pkt > 0);
/* Flush packets to network. */
switch (ossl_qtx_flush_net(ch->qtx)) {