QUIC CHANNEL: Only handle the first protocol error raised
authorHugo Landau <hlandau@openssl.org>
Wed, 9 Aug 2023 16:46:32 +0000 (17:46 +0100)
committerHugo Landau <hlandau@openssl.org>
Fri, 1 Sep 2023 09:45:33 +0000 (10:45 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21715)

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

index 516b895d8df20a76cd9ab670a289ccafd7469e59..844ddc137c552eb2e69b86c7a1ee652a06340546 100644 (file)
@@ -2930,6 +2930,10 @@ static void ch_start_terminating(QUIC_CHANNEL *ch,
                                  const QUIC_TERMINATE_CAUSE *tcause,
                                  int force_immediate)
 {
+    /* No point sending anything if we haven't sent anything yet. */
+    if (!ch->have_sent_any_pkt)
+        force_immediate = 1;
+
     switch (ch->state) {
     default:
     case QUIC_CHANNEL_STATE_IDLE:
@@ -3250,6 +3254,10 @@ void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch,
     const char *ft_str = NULL;
     const char *ft_str_pfx = " (", *ft_str_sfx = ")";
 
+    if (ch->protocol_error)
+        /* Only the first call to this function matters. */
+        return;
+
     if (err_str == NULL) {
         err_str     = "";
         err_str_pfx = "";
@@ -3297,6 +3305,7 @@ void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch,
     tcause.reason     = reason;
     tcause.reason_len = strlen(reason);
 
+    ch->protocol_error = 1;
     ch_start_terminating(ch, &tcause, 0);
 }
 
index 8cef1372552f8d5f931c623685a9ef921fe79f40..a60a539f9bbf38150ce0088fa752fd45d557b20e 100644 (file)
@@ -445,6 +445,14 @@ struct quic_channel_st {
     /* Permanent net error encountered */
     unsigned int                    net_error                           : 1;
 
+    /*
+     * Protocol error encountered. Note that you should refer to the state field
+     * rather than this. This is only used so we can ignore protocol errors
+     * after the first protocol error, but still record the first protocol error
+     * if it happens during the TERMINATING state.
+     */
+    unsigned int                    protocol_error                      : 1;
+
     /* Inhibit tick for testing purposes? */
     unsigned int                    inhibit_tick                        : 1;