Skip to content

Commit 83c744c

Browse files
committed
Bug#35833873 Suppress excessive NDB TLS errors
Suppress logging of "error:0A000126:SSL routines::unexpected eof while reading". Suppress logging of "SSL_shutdown: error:0A000197:SSL routines::shutdown while in init" by not calling SSL_shutdown if deciable in advance that it will fail. Suppress logging some errors for SSL_read_ex, SSL_peek_ex, SSL_write_ex by not calling them if connection is shutdown. Also change NdbSocket::ssl_handshake to use handle_ssl_error instead of calling log_ssl_error assumming all failures are SSL_ERROR_SSL. Change-Id: Ifee36ce4bacfd3966468623bccdec5750670ac1f
1 parent 141ef03 commit 83c744c

File tree

2 files changed

+67
-44
lines changed

2 files changed

+67
-44
lines changed

storage/ndb/include/util/ndb_openssl3_compat.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
#include <openssl/ssl.h>
3333
#include "portlib/ndb_openssl_version.h"
3434

35+
#ifndef SSL_R_UNEXPECTED_EOF_WHILE_READING
36+
// Macro not defined in OpenSSL 1.x headers (Brought in via ssl.h for OSSL3.0)
37+
#define SSL_R_UNEXPECTED_EOF_WHILE_READING 294
38+
#endif
39+
3540
#if OPENSSL_VERSION_NUMBER < 0x30000000L && OPENSSL_VERSION_NUMBER > 0x10002000L
3641

3742
EVP_PKEY * EVP_RSA_gen(unsigned int bits);

storage/ndb/src/common/util/NdbSocket.cpp

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,13 @@
2727
#include "openssl/err.h"
2828

2929
#include "debugger/EventLogger.hpp"
30+
#include "portlib/ndb_openssl_version.h"
3031
#include "portlib/NdbTick.h"
31-
32-
#include "util/require.h"
32+
#include "util/ndb_openssl3_compat.h"
3333
#include "util/NdbSocket.h"
34+
#include "util/require.h"
3435
#include "util/socket_io.h"
3536

36-
#include "portlib/ndb_openssl_version.h"
37-
3837
static constexpr bool openssl_version_ok =
3938
(OPENSSL_VERSION_NUMBER >= NDB_TLS_MINIMUM_OPENSSL);
4039

@@ -134,31 +133,24 @@ int NdbSocket::set_nonblocking(int on) const {
134133

135134
static void log_ssl_error(const char * fn_name)
136135
{
137-
char buffer[512];
138-
int code;
139-
while((code = ERR_get_error()) != 0) {
140-
ERR_error_string_n(code, buffer, sizeof(buffer));
141-
g_eventLogger->error("NDB TLS %s: %s", fn_name, buffer);
136+
const int code = ERR_peek_last_error();
137+
if (ERR_GET_REASON(code) == SSL_R_UNEXPECTED_EOF_WHILE_READING) {
138+
/*
139+
* "unexpected eof while reading" are in general expected to happen now and
140+
* then when network or peer breaks - logging is suppressed to limit
141+
* harmless noise.
142+
*/
143+
while (ERR_get_error() != 0) /* clear queued errors */ ;
144+
return ;
142145
}
143-
}
144-
145-
bool NdbSocket::ssl_handshake() {
146-
/* Check for non-blocking socket (see set_nonblocking): */
147-
if(SSL_get_mode(ssl) & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) return false;
148-
assert(SSL_get_mode(ssl) & SSL_MODE_AUTO_RETRY);
149-
150-
int r = SSL_do_handshake(ssl);
151-
if(r == 1) return true;
152-
153-
int err = SSL_get_error(ssl, r);
154-
require(err != SSL_ERROR_WANT_READ); // always use blocking I/O for handshake
155-
require(err != SSL_ERROR_WANT_WRITE);
156-
const char * desc = SSL_is_server(ssl) ?
157-
"handshake failed in server" : "handshake failed in client";
158-
159-
log_ssl_error(desc);
160-
close();
161-
return false;
146+
char buffer[512];
147+
ERR_error_string_n(code, buffer, sizeof(buffer));
148+
g_eventLogger->error("NDB TLS %s: %s", fn_name, buffer);
149+
#if defined(VM_TRACE) || !defined(NDEBUG) || defined(ERROR_INSERT)
150+
/* Check that there is at least one error in queue. */
151+
require(ERR_get_error() != 0);
152+
#endif
153+
while (ERR_get_error() != 0) /* clear queued errors */ ;
162154
}
163155

164156
/* This is only used by read & write routines */
@@ -188,22 +180,43 @@ static ssize_t handle_ssl_error(int err, const char * fn) {
188180
}
189181
}
190182

183+
bool NdbSocket::ssl_handshake() {
184+
/* Check for non-blocking socket (see set_nonblocking): */
185+
if(SSL_get_mode(ssl) & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) return false;
186+
assert(SSL_get_mode(ssl) & SSL_MODE_AUTO_RETRY);
187+
188+
int r = SSL_do_handshake(ssl);
189+
if(r == 1) return true;
190+
191+
int err = SSL_get_error(ssl, r);
192+
require(err != SSL_ERROR_WANT_READ); // always use blocking I/O for handshake
193+
require(err != SSL_ERROR_WANT_WRITE);
194+
const char * desc = SSL_is_server(ssl) ?
195+
"handshake failed in server" : "handshake failed in client";
196+
197+
handle_ssl_error(err, desc);
198+
close();
199+
return false;
200+
}
201+
191202
// ssl_close
192203
void NdbSocket::ssl_close() {
193204
Guard guard(mutex);
194-
const int mode = SSL_get_shutdown(ssl);
195-
if (!(mode & SSL_SENT_SHUTDOWN)) {
196-
/*
197-
* Do not call SSL_shutdown again if it already been called in
198-
* NdbSocket::shutdown. In that case it could block waiting on
199-
* SSL_RECEIVED_SHUTDOWN.
200-
*/
201-
int r = SSL_shutdown(ssl);
202-
if (r < 0) {
203-
// Clear errors
204-
int err = SSL_get_error(ssl, r);
205-
Debug_Log("SSL_shutdown(): ERR %d", err);
206-
handle_ssl_error(err, "SSL_close");
205+
if (SSL_is_init_finished(ssl)) {
206+
const int mode = SSL_get_shutdown(ssl);
207+
if (!(mode & SSL_SENT_SHUTDOWN)) {
208+
/*
209+
* Do not call SSL_shutdown again if it already been called in
210+
* NdbSocket::shutdown. In that case it could block waiting on
211+
* SSL_RECEIVED_SHUTDOWN.
212+
*/
213+
int r = SSL_shutdown(ssl);
214+
if (r < 0) {
215+
// Clear errors
216+
int err = SSL_get_error(ssl, r);
217+
Debug_Log("SSL_shutdown(): ERR %d", err);
218+
handle_ssl_error(err, "SSL_close");
219+
}
207220
}
208221
}
209222
SSL_free(ssl);
@@ -237,6 +250,11 @@ int NdbSocket::ssl_shutdown() const {
237250
int err;
238251
{
239252
Guard guard(mutex);
253+
/*
254+
* SSL_is_init_finished may return false if either TLS handshake have not
255+
* finished, or an unexpected eof was seen.
256+
*/
257+
if (!SSL_is_init_finished(ssl)) return 0;
240258
const int mode = SSL_get_shutdown(ssl);
241259
assert(!(mode & SSL_SENT_SHUTDOWN));
242260
if (unlikely(mode & SSL_SENT_SHUTDOWN)) return 0;
@@ -255,7 +273,7 @@ ssize_t NdbSocket::ssl_recv(char *buf, size_t len) const
255273
int err;
256274
{
257275
Guard guard(mutex);
258-
if(unlikely(ssl == nullptr || SSL_get_shutdown(ssl)))
276+
if(unlikely(ssl == nullptr || SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN))
259277
return 0;
260278

261279
r = SSL_read_ex(ssl, buf, len, &nread);
@@ -274,7 +292,7 @@ ssize_t NdbSocket::ssl_peek(char *buf, size_t len) const
274292
int err;
275293
{
276294
Guard guard(mutex);
277-
if(unlikely(ssl == nullptr || SSL_get_shutdown(ssl)))
295+
if(unlikely(ssl == nullptr || SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN))
278296
return 0;
279297

280298
r = SSL_peek_ex(ssl, buf, len, &nread);
@@ -294,7 +312,7 @@ ssize_t NdbSocket::ssl_send(const char * buf, size_t len) const
294312
/* Locked section */
295313
{
296314
Guard guard(mutex);
297-
if(unlikely(ssl == nullptr || SSL_get_shutdown(ssl)))
315+
if(unlikely(ssl == nullptr || SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN))
298316
return -1;
299317

300318
if(SSL_write_ex(ssl, buf, len, &nwrite))

0 commit comments

Comments
 (0)