QUIC TXP: Allow caller to determine if an ACK-eliciting packet was sent
authorHugo Landau <hlandau@openssl.org>
Tue, 21 Feb 2023 10:18:59 +0000 (10:18 +0000)
committerHugo Landau <hlandau@openssl.org>
Thu, 30 Mar 2023 10:14:08 +0000 (11:14 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20348)

include/internal/quic_txp.h
ssl/quic/quic_txp.c
test/quic_txp_test.c

index e58eb15d486914cb4b73bfbb612b9e0a1dc17410..fb553f97e5951481a9e194865a673b6e6fe52df7 100644 (file)
@@ -81,12 +81,16 @@ void ossl_quic_tx_packetiser_free(OSSL_QUIC_TX_PACKETISER *txp);
  * Returns TX_PACKETISER_RES_FAILURE on failure (e.g. allocation error),
  * TX_PACKETISER_RES_NO_PKT if no packets were sent (e.g. because nothing wants
  * to send anything), and TX_PACKETISER_RES_SENT_PKT if packets were sent.
+ *
+ * If an ACK-eliciting packet was sent, 1 is written to *sent_ack_eliciting,
+ * otherwise *sent_ack_eliciting is unchanged.
  */
 #define TX_PACKETISER_RES_FAILURE   0
 #define TX_PACKETISER_RES_NO_PKT    1
 #define TX_PACKETISER_RES_SENT_PKT  2
 int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp,
-                                     uint32_t archetype);
+                                     uint32_t archetype,
+                                     int *sent_ack_eliciting);
 
 /*
  * Returns 1 if one or more packets would be generated if
index 0f3383875c6a63fb52fe6eb05544fb5e754bb9fb..2d49e64f7ffd7c24ed195ef1dac6c9493322f78b 100644 (file)
@@ -320,7 +320,8 @@ static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level,
                                int cc_can_send,
                                int is_last_in_dgram,
                                int dgram_contains_initial,
-                               int chosen_for_conn_close);
+                               int chosen_for_conn_close,
+                               int *sent_ack_eliciting);
 static size_t txp_determine_pn_len(OSSL_QUIC_TX_PACKETISER *txp);
 static int txp_determine_ppl_from_pl(OSSL_QUIC_TX_PACKETISER *txp,
                                      size_t pl,
@@ -335,7 +336,8 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
                                       size_t max_ppl,
                                       size_t pkt_overhead,
                                       QUIC_PKT_HDR *phdr,
-                                      int chosen_for_conn_close);
+                                      int chosen_for_conn_close,
+                                      int *sent_ack_eliciting);
 
 OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETISER_ARGS *args)
 {
@@ -499,7 +501,8 @@ int ossl_quic_tx_packetiser_has_pending(OSSL_QUIC_TX_PACKETISER *txp,
  * any ELs which do.
  */
 int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp,
-                                     uint32_t archetype)
+                                     uint32_t archetype,
+                                     int *sent_ack_eliciting)
 {
     uint32_t enc_level, conn_close_enc_level = QUIC_ENC_LEVEL_NUM;
     int have_pkt_for_el[QUIC_ENC_LEVEL_NUM], is_last_in_dgram, cc_can_send;
@@ -540,7 +543,8 @@ int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp,
         rc = txp_generate_for_el(txp, enc_level, archetype, cc_can_send,
                                  is_last_in_dgram,
                                  have_pkt_for_el[QUIC_ENC_LEVEL_INITIAL],
-                                 enc_level == conn_close_enc_level);
+                                 enc_level == conn_close_enc_level,
+                                 sent_ack_eliciting);
 
         if (rc != TXP_ERR_SUCCESS) {
             /*
@@ -888,7 +892,8 @@ static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level,
                                int cc_can_send,
                                int is_last_in_dgram,
                                int dgram_contains_initial,
-                               int chosen_for_conn_close)
+                               int chosen_for_conn_close,
+                               int *sent_ack_eliciting)
 {
     int must_pad = dgram_contains_initial && is_last_in_dgram;
     size_t min_dpl, min_pl, min_ppl, cmpl, cmppl, running_total;
@@ -1010,7 +1015,8 @@ static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level,
 
     return txp_generate_for_el_actual(txp, enc_level, archetype, min_ppl, cmppl,
                                       pkt_overhead, &phdr,
-                                      chosen_for_conn_close);
+                                      chosen_for_conn_close,
+                                      sent_ack_eliciting);
 }
 
 /* Determine how many bytes we should use for the encoded PN. */
@@ -1810,7 +1816,8 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
                                       size_t max_ppl,
                                       size_t pkt_overhead,
                                       QUIC_PKT_HDR *phdr,
-                                      int chosen_for_conn_close)
+                                      int chosen_for_conn_close,
+                                      int *sent_ack_eliciting)
 {
     int rc = TXP_ERR_SUCCESS;
     struct archetype_data a;
@@ -2224,6 +2231,9 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
             --probe_info->pto[pn_space];
     }
 
+    if (have_ack_eliciting)
+        *sent_ack_eliciting = 1;
+
     /* Done. */
     tx_helper_cleanup(&h);
     return rc;
index edc7b25e9a9bb556f81c528213d39614be907091..f06002f26ac9ad82dd367fbfc27e6c1e1e019565 100644 (file)
@@ -1206,7 +1206,7 @@ static void skip_padding(struct helper *h)
 
 static int run_script(const struct script_op *script)
 {
-    int testresult = 0, have_helper = 0;
+    int testresult = 0, have_helper = 0, sent_ack_eliciting = 0;
     struct helper h;
     const struct script_op *op;
 
@@ -1217,7 +1217,8 @@ static int run_script(const struct script_op *script)
     for (op = script; op->opcode != OPK_END; ++op) {
         switch (op->opcode) {
         case OPK_TXP_GENERATE:
-            if (!TEST_int_eq(ossl_quic_tx_packetiser_generate(h.txp, (int)op->arg0),
+            if (!TEST_int_eq(ossl_quic_tx_packetiser_generate(h.txp, (int)op->arg0,
+                                                              &sent_ack_eliciting),
                              TX_PACKETISER_RES_SENT_PKT))
                 goto err;
 
@@ -1225,7 +1226,8 @@ static int run_script(const struct script_op *script)
             ossl_qtx_flush_net(h.args.qtx);
             break;
         case OPK_TXP_GENERATE_NONE:
-            if (!TEST_int_eq(ossl_quic_tx_packetiser_generate(h.txp, (int)op->arg0),
+            if (!TEST_int_eq(ossl_quic_tx_packetiser_generate(h.txp, (int)op->arg0,
+                                                              &sent_ack_eliciting),
                              TX_PACKETISER_RES_NO_PKT))
                 goto err;