SSL: set c->error on connection reset SSL_read() error.

It is possible to receive application data together with socket close.
In this case, SSL_read() may return SSL_ERROR_SYSCALL with ECONNRESET,
specifically after OpenSSL sent TLSv1.3 tickets on a closed connection.

Before OpenSSL 4.0, the behaviour was to return SSL_ERROR_SYSCALL with
EPIPE from a subsequent SSL_write() on such a connection state.  It was
intentionally changed to handle such a call as a protocol error, see
https://github.com/openssl/openssl/issues/30631 for details.
This makes SSL_write() to return SSL_ERROR_SSL with the empty error
queue, which leads to critical errors, as caught by ssl_stapling.t.
Setting c->error is used to avoid calling SSL_write() in this case.
This commit is contained in:
Sergey Kandaurov 2026-04-14 11:56:56 +04:00
parent bbaac1d43f
commit 142f21f43b

View file

@ -2982,6 +2982,10 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
c->ssl->no_wait_shutdown = 1;
c->ssl->no_send_shutdown = 1;
if (err == NGX_ECONNRESET) {
c->error = 1;
}
if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"peer shutdown SSL cleanly");