QUIC_CHANNEL: Handle deferred packet processing after yielding of secrets correctly
authorHugo Landau <hlandau@openssl.org>
Fri, 18 Nov 2022 17:25:25 +0000 (17:25 +0000)
committerHugo Landau <hlandau@openssl.org>
Fri, 13 Jan 2023 13:20:17 +0000 (13:20 +0000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19703)

ssl/quic/quic_channel.c
ssl/quic/quic_channel_local.h

index 7da3095ee119f435d7e11b1c1bedcf6fab633c0e..04f87c92925eee7317bd7f413d45d247b7f3b351 100644 (file)
@@ -531,6 +531,7 @@ static int ch_on_handshake_yield_secret(uint32_t enc_level, int direction,
             return 0;
     }
 
+    ch->have_new_secret = 1;
     return 1;
 }
 
@@ -1007,14 +1008,23 @@ static void ch_tick(QUIC_TICK_RESULT *res, void *arg)
         }
     }
 
-    /* Handle any incoming data from the network. */
-    ch_rx(ch);
+    do {
+        /* Handle any incoming data from the network. */
+        ch_rx(ch);
 
-    /*
-     * Allow the handshake layer to check for any new incoming data and generate
-     * new outgoing data.
-     */
-    ossl_quic_dhs_tick(ch->dhs);
+        /*
+         * Allow the handshake layer to check for any new incoming data and generate
+         * new outgoing data.
+         */
+        ch->have_new_secret = 0;
+        ossl_quic_dhs_tick(ch->dhs);
+
+        /*
+         * 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.
+         */
+    } while (ch->have_new_secret);
 
     /*
      * Handle any timer events which are due to fire; namely, the loss detection
index 5859c0391a48d94c76e00d9c348f3b4a5676705e..88e49d588c1a4dcc74310061d3baf2251c053fef 100644 (file)
@@ -263,6 +263,12 @@ struct quic_channel_st {
 
     /* Are we in server mode? Never changes after instantiation. */
     unsigned int                    is_server               : 1;
+
+    /*
+     * Set temporarily when the handshake layer has given us a new secret. Used
+     * to determine if we need to check our RX queues again.
+     */
+    unsigned int                    have_new_secret         : 1;
 };
 
 # endif