Carry TLS error strings forward to controller when reporting them.

Now instead of saying "DONE, DONE" or "MISC, MISC" or "TLS_ERROR,
TLS_ERROR",  we can finally give a nice sensible "TLS_ERROR,
wrong version number" which should help debug a great deal.

Closes ticket 32622.
This commit is contained in:
Nick Mathewson 2020-06-26 11:18:38 -04:00
parent e429ceb266
commit 7b5f58a1c9
5 changed files with 47 additions and 4 deletions

View File

@ -745,10 +745,16 @@ connection_or_about_to_close(or_connection_t *or_conn)
int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
connection_or_event_status(or_conn, OR_CONN_EVENT_FAILED,
reason);
if (!authdir_mode_tests_reachability(options))
control_event_bootstrap_prob_or(
orconn_end_reason_to_control_string(reason),
reason, or_conn);
if (!authdir_mode_tests_reachability(options)) {
const char *warning = NULL;
if (reason == END_OR_CONN_REASON_TLS_ERROR && or_conn->tls) {
warning = tor_tls_get_last_error_msg(or_conn->tls);
}
if (warning == NULL) {
warning = orconn_end_reason_to_control_string(reason);
}
control_event_bootstrap_prob_or(warning, reason, or_conn);
}
}
}
} else if (conn->hold_open_until_flushed) {

View File

@ -81,6 +81,7 @@ void tor_tls_free_all(void);
void tor_tls_init(void);
void tls_log_errors(tor_tls_t *tls, int severity, int domain,
const char *doing);
const char *tor_tls_get_last_error_msg(const tor_tls_t *tls);
int tor_tls_context_init(unsigned flags,
crypto_pk_t *client_identity,
crypto_pk_t *server_identity,

View File

@ -369,6 +369,8 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain,
(void)tls;
PRErrorCode code = PORT_GetError();
if (tls)
tls->last_error = code;
const char *addr = tls ? tls->address : NULL;
const char *string = PORT_ErrorToString(code);
@ -391,6 +393,17 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain,
with, addr);
}
}
const char *
tor_tls_get_last_error_msg(const tor_tls_t *tls)
{
IF_BUG_ONCE(!tls) {
return NULL;
}
if (tls->last_error == 0) {
return NULL;
}
return PORT_ErrorToString((PRErrorCode)tls->last_error);
}
tor_tls_t *
tor_tls_new(tor_socket_t sock, int is_server)

View File

@ -245,10 +245,30 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing)
unsigned long err;
while ((err = ERR_get_error()) != 0) {
if (tls)
tls->last_error = err;
tor_tls_log_one_error(tls, err, severity, domain, doing);
}
}
/**
* Return a string representing more detail about the last error received
* on TLS.
*
* May return null if no error was found.
**/
const char *
tor_tls_get_last_error_msg(const tor_tls_t *tls)
{
IF_BUG_ONCE(!tls) {
return NULL;
}
if (tls->last_error == 0) {
return NULL;
}
return (const char*)ERR_reason_error_string(tls->last_error);
}
#define CATCH_SYSCALL 1
#define CATCH_ZERO 2

View File

@ -67,6 +67,8 @@ struct tor_tls_t {
*/
unsigned long last_write_count;
unsigned long last_read_count;
/** Most recent error value from ERR_get_error(). */
unsigned long last_error;
/** If set, a callback to invoke whenever the client tries to renegotiate
* the handshake. */
void (*negotiated_callback)(tor_tls_t *tls, void *arg);
@ -77,6 +79,7 @@ struct tor_tls_t {
/** Last values retried from tor_get_prfiledesc_byte_counts(). */
uint64_t last_write_count;
uint64_t last_read_count;
long last_error;
#endif
};