From 26d081d500f2e20de3242543df2bfc1bc37c0167 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Sat, 14 Dec 2019 16:22:10 +0100 Subject: [PATCH] connectd: translate socks5 errors to human strings For example: "Tor connect out for host example.com error: 4 " becomes: "Error connecting to example.com: Tor server reply: host unreachable" Also clarify the error: "Connected out for example.com error" to: "Connected out for example.com error: authentication required" because the only reason it could have failed is that the Tor socks5 server did not like any of our proposed auth methods and we only proposed "no auth". Changelog-None --- connectd/tor.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/connectd/tor.c b/connectd/tor.c index 6a3951b34..c26ee87f0 100644 --- a/connectd/tor.c +++ b/connectd/tor.c @@ -41,6 +41,32 @@ struct connecting_socks { struct connecting *connect; }; +static const char* socks5strerror(const tal_t *ctx, u8 code) +{ + // Error codes defined in https://tools.ietf.org/html/rfc1928#section-6 + switch (code) { + case 0: + return tal_strdup(ctx, "success"); + case 1: + return tal_strdup(ctx, "general SOCKS server failure"); + case 2: + return tal_strdup(ctx, "connection not allowed by ruleset"); + case 3: + return tal_strdup(ctx, "network unreachable"); + case 4: + return tal_strdup(ctx, "host unreachable"); + case 5: + return tal_strdup(ctx, "connection refused"); + case 6: + return tal_strdup(ctx, "TTL expired"); + case 7: + return tal_strdup(ctx, "command not supported"); + case 8: + return tal_strdup(ctx, "address type not supported"); + } + return tal_fmt(ctx, "unknown error: %d", code); +} + static struct io_plan *connect_finish2(struct io_conn *conn, struct connecting_socks *connect) { @@ -57,6 +83,9 @@ static struct io_plan *connect_finish(struct io_conn *conn, status_io(LOG_IO_IN, NULL, "proxy", connect->buffer, SIZE_OF_IPV4_RESPONSE + SIZE_OF_RESPONSE); + /* buffer[1] contains the reply status code and 0 means "success", + * see https://tools.ietf.org/html/rfc1928#section-6 + */ if ( connect->buffer[1] == '\0') { if ( connect->buffer[3] == SOCKS_TYP_IPV6) { /* Read rest of response */ @@ -73,13 +102,15 @@ static struct io_plan *connect_finish(struct io_conn *conn, return connection_out(conn, connect->connect); } else { status_debug - ("Tor connect out for host %s error invalid type return ", - connect->host); + ("Tor connect out for host %s error invalid " + "type return: %0x", connect->host, + connect->buffer[3]); return io_close(conn); } } else { - status_debug("Tor connect out for host %s error: %x ", - connect->host, connect->buffer[1]); + status_debug("Error connecting to %s: Tor server reply: %s", + connect->host, + socks5strerror(tmpctx, connect->buffer[1])); return io_close(conn); } } @@ -103,7 +134,10 @@ static struct io_plan *io_tor_connect_after_resp_to_connect(struct io_conn status_io(LOG_IO_IN, NULL, "proxy", connect->buffer, 2); if (connect->buffer[1] == SOCKS_ERROR) { - status_debug("Connected out for %s error", connect->host); + // The Tor socks5 server did not like any of our authentication + // methods and we provided only "no auth". + status_debug("Connected out for %s error: authentication required", + connect->host); return io_close(conn); } /* make the V5 request */