]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
QUIC TXP: Handle non-inflight-eligible packets correctly
authorHugo Landau <hlandau@openssl.org>
Mon, 3 Jul 2023 14:45:25 +0000 (15:45 +0100)
committerPauli <pauli@openssl.org>
Wed, 19 Jul 2023 03:03:11 +0000 (13:03 +1000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21349)

ssl/quic/quic_txp.c

index 959186d4a64be44260b20e252bd8c776451c5ac0..f22f2cb5dd00f4fa953358ac0a172ae79658932a 100644 (file)
@@ -1274,7 +1274,8 @@ static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp,
                                   QUIC_TXPIM_PKT *tpkt,
                                   uint32_t pn_space,
                                   struct archetype_data *a,
-                                  int chosen_for_conn_close)
+                                  int chosen_for_conn_close,
+                                  int *can_be_non_inflight)
 {
     const OSSL_QUIC_FRAME_ACK *ack;
     OSSL_QUIC_FRAME_ACK ack2;
@@ -1350,6 +1351,8 @@ static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp,
         if (ossl_quic_wire_encode_frame_conn_close(wpkt, pf)) {
             if (!tx_helper_commit(h))
                 return 0;
+
+            *can_be_non_inflight = 0;
         } else {
             tx_helper_rollback(h);
         }
@@ -2026,6 +2029,15 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
     uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level);
     struct tx_helper h;
     int have_helper = 0, have_ack_eliciting = 0, done_pre_token = 0;
+    /*
+     * Cleared if we encode any non-ACK-eliciting frame type which rules out the
+     * packet being a non-inflight frame. This means any non-ACK ACK-eliciting
+     * frame, even PADDING frames. ACK eliciting frames always cause a packet to
+     * become ineligible for non-inflight treatment so it is not necessary to
+     * clear this in cases where have_ack_eliciting is set, as it is ignored in
+     * that case.
+     */
+    int can_be_non_inflight = 1;
     int require_ack_eliciting = 0;
     QUIC_CFQ_ITEM *cfq_item;
     QUIC_TXPIM_PKT *tpkt = NULL;
@@ -2205,7 +2217,8 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
                  */
                 if (!done_pre_token)
                     if (txp_generate_pre_token(txp, &h, tpkt, pn_space, &a,
-                                               chosen_for_conn_close))
+                                               chosen_for_conn_close,
+                                               &can_be_non_inflight))
                         done_pre_token = 1;
 
                 break;
@@ -2239,7 +2252,8 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
      */
     if (!done_pre_token)
         if (txp_generate_pre_token(txp, &h, tpkt, pn_space, &a,
-                                   chosen_for_conn_close))
+                                   chosen_for_conn_close,
+                                   &can_be_non_inflight))
             done_pre_token = 1;
 
     /* CRYPTO Frames */
@@ -2285,18 +2299,23 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
         if (!ossl_quic_wire_encode_padding(wpkt, min_ppl - h.bytes_appended)
             || !tx_helper_commit(&h))
             goto fatal_err;
+
+        can_be_non_inflight = 0;
     }
 
     /*
      * Dispatch
      * ========
      */
+    if (have_ack_eliciting)
+        can_be_non_inflight = 0;
+
     /* ACKM Data */
     tpkt->ackm_pkt.num_bytes        = h.bytes_appended + pkt_overhead;
     tpkt->ackm_pkt.pkt_num          = txp->next_pn[pn_space];
     /* largest_acked is set in txp_generate_pre_token */
     tpkt->ackm_pkt.pkt_space        = pn_space;
-    tpkt->ackm_pkt.is_inflight      = 1;
+    tpkt->ackm_pkt.is_inflight      = !can_be_non_inflight;
     tpkt->ackm_pkt.is_ack_eliciting = have_ack_eliciting;
     tpkt->ackm_pkt.is_pto_probe     = 0;
     tpkt->ackm_pkt.is_mtu_probe     = 0;