diff options
author | Hugo Landau <hlandau@openssl.org> | 2023-08-09 17:46:32 +0100 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2023-09-01 10:45:33 +0100 |
commit | 549d0a700be311d9a65560cb9eed3f725546b5ed (patch) | |
tree | ff38af9f39ae6b5d66ef2c8b947fee67372406b3 | |
parent | 7841dbabec50eb701022154d9639a01c2a875eaa (diff) |
QUIC CHANNEL: Only handle the first protocol error raised
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21715)
-rw-r--r-- | ssl/quic/quic_channel.c | 9 | ||||
-rw-r--r-- | ssl/quic/quic_channel_local.h | 8 |
2 files changed, 17 insertions, 0 deletions
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 516b895d8d..844ddc137c 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -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); } diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h index 8cef137255..a60a539f9b 100644 --- a/ssl/quic/quic_channel_local.h +++ b/ssl/quic/quic_channel_local.h @@ -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; |