};
};
+/*
+ * This function gives the detail of the SSL error. It is used only
+ * if the debug mode and the verbose mode are activated. It dump all
+ * the SSL error until the stack was empty.
+ */
+static forceinline void ssl_sock_dump_errors(struct connection *conn)
+{
+ unsigned long ret;
+
+ if (unlikely(global.mode & MODE_DEBUG)) {
+ while(1) {
+ ret = ERR_get_error();
+ if (ret == 0)
+ return;
+ fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
+ (unsigned short)conn->t.sock.fd, ret,
+ ERR_func_error_string(ret), ERR_reason_error_string(ret));
+ }
+ }
+}
+
/*
* This function returns the number of seconds elapsed
* since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
}
if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
+ ssl_sock_dump_errors(conn);
ERR_clear_error();
return 1;
}
/* check if certificate error needs to be ignored */
if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
+ ssl_sock_dump_errors(conn);
ERR_clear_error();
return 1;
}
out_error:
/* Clear openssl global errors stack */
+ ssl_sock_dump_errors(conn);
ERR_clear_error();
/* free resumed session if exists */
conn->flags |= CO_FL_ERROR;
/* Clear openssl global errors stack */
+ ssl_sock_dump_errors(conn);
ERR_clear_error();
}
goto read0;
return done;
out_error:
/* Clear openssl global errors stack */
+ ssl_sock_dump_errors(conn);
ERR_clear_error();
conn->flags |= CO_FL_ERROR;
out_error:
/* Clear openssl global errors stack */
+ ssl_sock_dump_errors(conn);
ERR_clear_error();
conn->flags |= CO_FL_ERROR;
/* no handshake was in progress, try a clean ssl shutdown */
if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
/* Clear openssl global errors stack */
+ ssl_sock_dump_errors(conn);
ERR_clear_error();
}
#ifndef OPENSSL_NO_DH
ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
#endif
+
+ /* Load SSL string for the verbose & debug mode. */
+ ERR_load_SSL_strings();
}
__attribute__((destructor))