SSL_get_error.
if(res->ssl) {
ERR_clear_error();
if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) {
- if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) {
+ int r2;
+ if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN) {
verbose(VERB_QUERY, "warning, in SSL_write, peer "
"closed connection");
return 0;
}
- log_crypto_err("could not SSL_write");
+ log_crypto_err_io("could not SSL_write", r2);
return 0;
}
} else {
if(res->ssl) {
ERR_clear_error();
if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) {
- if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) {
+ int r2;
+ if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN) {
buf[len] = 0;
return 1;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", r2);
return 0;
}
} else {
if(res->ssl) {
ERR_clear_error();
if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) {
- if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN)
+ int r2;
+ if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN)
return;
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", r2);
return;
}
} else {
log_err("remote control connection closed prematurely");
log_addr(VERB_OPS, "failed connection from",
&s->c->repinfo.remote_addr, s->c->repinfo.remote_addrlen);
- log_crypto_err("remote control failed ssl");
+ log_crypto_err_io("remote control failed ssl", r2);
clean_point(rc, s);
}
return 0;
}
return -1;
}
- log_crypto_err("dnstap io, could not SSL_write");
+ log_crypto_err_io("dnstap io, could not SSL_write", want);
return -1;
}
return r;
"other side");
return 0;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", want);
verbose(VERB_DETAIL, "dnstap io: output closed by the "
"other side");
return 0;
} else {
unsigned long err = ERR_get_error();
if(!squelch_err_ssl_handshake(err)) {
- log_crypto_err_code("dnstap io, ssl handshake failed",
- err);
+ log_crypto_err_io_code("dnstap io, ssl handshake failed",
+ want, err);
verbose(VERB_OPS, "dnstap io, ssl handshake failed "
"from %s", dtio->ip_str);
}
(data->id?data->id:""));
return 0;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", want);
if(verbosity) log_info("dnstap client stream closed from %s",
(data->id?data->id:""));
return 0;
fd_set_block(data->fd);
if(data->ssl) {
if((r=SSL_write(data->ssl, acceptframe, len)) <= 0) {
- if(SSL_get_error(data->ssl, r) == SSL_ERROR_ZERO_RETURN)
+ int r2;
+ if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
log_err("SSL_write, peer closed connection");
else
- log_err("could not SSL_write");
+ log_crypto_err_io("could not SSL_write", r2);
fd_set_nonblock(data->fd);
free(acceptframe);
return 0;
if(data->ssl) {
int r;
if((r=SSL_write(data->ssl, finishframe, len)) <= 0) {
- if(SSL_get_error(data->ssl, r) == SSL_ERROR_ZERO_RETURN)
+ int r2;
+ if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
log_err("SSL_write, peer closed connection");
else
- log_err("could not SSL_write");
+ log_crypto_err_io("could not SSL_write", r2);
fd_set_nonblock(data->fd);
free(finishframe);
return 0;
+19 October 2023: Wouter
+ - Fix to print detailed errors when an SSL IO routine fails via
+ SSL_get_error.
+
18 October 2023: George
- Mailing list patches from Daniel Gröber for DNS64 fallback to plain
AAAA when no A record exists for synthesis, and minor DNS64 code
if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_EOF;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", want);
return NGHTTP2_ERR_EOF;
}
return r;
if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- log_crypto_err("could not SSL_write");
+ log_crypto_err_io("could not SSL_write", want);
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;
r = SSL_get_error(ssl, r);
if(r != SSL_ERROR_WANT_READ &&
r != SSL_ERROR_WANT_WRITE) {
- log_crypto_err("could not ssl_handshake");
+ log_crypto_err_io("could not ssl_handshake", r);
exit(1);
}
}
r = SSL_get_error(ssl, r);
if(r != SSL_ERROR_WANT_READ &&
r != SSL_ERROR_WANT_WRITE) {
- log_crypto_err("could not ssl_handshake");
+ log_crypto_err_io("could not ssl_handshake", r);
exit(1);
}
}
#endif /* HAVE_SSL */
}
+/** Print crypt erro with SSL_get_error want code and err_get_error code */
+static void log_crypto_err_io_code_arg(const char* str, int r,
+ unsigned long err, int err_present)
+{
+#ifdef HAVE_SSL
+ int print_errno = 0, print_crypto_err = 0;
+ const char* inf = NULL;
+
+ switch(r) {
+ case SSL_ERROR_NONE:
+ inf = "no error";
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ inf = "channel closed";
+ break;
+ case SSL_ERROR_WANT_READ:
+ inf = "want read";
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ inf = "want write";
+ break;
+ case SSL_ERROR_WANT_CONNECT:
+ inf = "want connect";
+ break;
+ case SSL_ERROR_WANT_ACCEPT:
+ inf = "want accept";
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ inf = "want X509 lookup";
+ break;
+ case SSL_ERROR_WANT_ASYNC:
+ inf = "want async";
+ break;
+ case SSL_ERROR_WANT_ASYNC_JOB:
+ inf = "want async job";
+ break;
+ case SSL_ERROR_WANT_CLIENT_HELLO_CB:
+ inf = "want client hello cb";
+ break;
+ case SSL_ERROR_SYSCALL:
+ print_errno = 1;
+ inf = "syscall";
+ break;
+ case SSL_ERROR_SSL:
+ print_crypto_err = 1;
+ inf = "SSL, usually protocol, error";
+ break;
+ default:
+ inf = "unknown SSL_get_error result code";
+ print_errno = 1;
+ print_crypto_err = 1;
+ }
+ if(print_crypto_err) {
+ if(print_errno) {
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%s with errno %s",
+ str, strerror(errno));
+ if(err_present)
+ log_crypto_err_code(buf, err);
+ else log_crypto_err(buf);
+ } else {
+ if(err_present)
+ log_crypto_err_code(str, err);
+ else log_crypto_err(str);
+ }
+ } else {
+ if(print_errno) {
+ if(errno == 0)
+ log_err("str: syscall error with errno %s",
+ strerror(errno));
+ else log_err("str: %s", strerror(errno));
+ } else {
+ log_err("str: %s", inf);
+ }
+ }
+#else
+ (void)str;
+ (void)r;
+ (void)err;
+ (void)err_present;
+#endif /* HAVE_SSL */
+}
+
+void log_crypto_err_io(const char* str, int r)
+{
+#ifdef HAVE_SSL
+ log_crypto_err_io_code_arg(str, r, 0, 0);
+#else
+ (void)str;
+ (void)r;
+#endif /* HAVE_SSL */
+}
+
+void log_crypto_err_io_code(const char* str, int r, unsigned long err)
+{
+#ifdef HAVE_SSL
+ log_crypto_err_io_code_arg(str, r, err, 1);
+#else
+ (void)str;
+ (void)r;
+ (void)err;
+#endif /* HAVE_SSL */
+}
+
#ifdef HAVE_SSL
/** log certificate details */
void
*/
void log_crypto_err_code(const char* str, unsigned long err);
+/**
+ * Log an error from libcrypto that came from SSL_write and so on, with
+ * a value from SSL_get_error, calls log_err. If that fails it logs with
+ * log_crypto_err.
+ * @param str: what failed
+ * @param r: output of SSL_get_error on the I/O operation result.
+ */
+void log_crypto_err_io(const char* str, int r);
+
+/**
+ * Log an error from libcrypt that came from an I/O routine with the
+ * errcode from ERR_get_error. Calls log_err() and log_crypto_err_code.
+ * @param str: what failed
+ * @param r: output of SSL_get_error on the I/O operation result.
+ * @param err: error code from ERR_get_error
+ */
+void log_crypto_err_io_code(const char* str, int r, unsigned long err);
+
/**
* Log certificate details verbosity, string, of X509 cert
* @param level: verbosity level
} else {
unsigned long err = ERR_get_error();
if(!squelch_err_ssl_handshake(err)) {
- log_crypto_err_code("ssl handshake failed", err);
+ log_crypto_err_io_code("ssl handshake failed",
+ want, err);
log_addr(VERB_OPS, "ssl handshake failed",
&c->repinfo.remote_addr,
c->repinfo.remote_addrlen);
strerror(errno));
return 0;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read",
+ want);
return 0;
}
c->tcp_byte_count += r;
strerror(errno));
return 0;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read",
+ want);
return 0;
}
c->tcp_byte_count += r;
strerror(errno));
return 0;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", want);
return 0;
}
c->tcp_byte_count += r;
strerror(errno));
return 0;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", want);
return 0;
}
sldns_buffer_skip(c->buffer, (ssize_t)r);
strerror(errno));
return 0;
}
- log_crypto_err("could not SSL_write");
+ log_crypto_err_io("could not SSL_write", want);
return 0;
}
if(c->tcp_write_and_read) {
strerror(errno));
return 0;
}
- log_crypto_err("could not SSL_write");
+ log_crypto_err_io("could not SSL_write", want);
return 0;
}
if(c->tcp_write_and_read) {
strerror(errno));
return 0;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", want);
return 0;
}
verbose(VERB_ALGO, "ssl http read more skip to %d + %d",
strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- log_crypto_err("could not SSL_read");
+ log_crypto_err_io("could not SSL_read", want);
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;
strerror(errno));
return 0;
}
- log_crypto_err("could not SSL_write");
+ log_crypto_err_io("could not SSL_write", want);
return 0;
}
sldns_buffer_skip(c->buffer, (ssize_t)r);
strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- log_crypto_err("could not SSL_write");
+ log_crypto_err_io("could not SSL_write", want);
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;