SSL: avoid writing to a connection with a failed read
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, a subsequent SSL_write() returned SSL_ERROR_SYSCALL
with EPIPE in this case. The behaviour was changed to remember the
error state and handle such a call as a protocol error, see for details
https://github.com/openssl/openssl/issues/30631. This makes SSL_write()
return SSL_ERROR_SSL with the empty error queue, which results in
"[crit] ... SSL_write() failed" errors, as caught by ssl_stapling.t.
The fix is to check the result of the last read stored in c->ssl->last,
to avoid calling SSL_write() after a failed read. For consistency, the
check is added to ngx_ssl_sendfile(): SSL_sendfile() resets the error
state the same way SSL_write() does, though it does not seem to be
reachable in http.
Based on a patch by Maxim Dounin.
Signed-off-by: Sergey Kandaurov <pluknet@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/
ff5becaf5444>