From f6d3dc3d9e0e70f2c553ce254b49630bd98910e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arturo=20Filast=C3=B2?= Date: Sat, 16 Jun 2012 13:51:21 +0200 Subject: Implement feature #6031 based on review by rransom * Return SOCKS code 0x23 when HS is not found * Return SOCKS code 0x24 when HS is not reachable --- src/common/compat.h | 2 ++ src/or/or.h | 5 +++++ src/or/reasons.c | 8 ++++++++ src/or/rendclient.c | 25 +++++++++++++++++++++---- src/tools/tor-resolve.c | 4 ++++ 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/common/compat.h b/src/common/compat.h index 4efb0c8b8..6a16891c5 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -542,6 +542,8 @@ typedef enum { SOCKS5_TTL_EXPIRED = 0x06, SOCKS5_COMMAND_NOT_SUPPORTED = 0x07, SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08, + SOCKS5_HS_NOT_FOUND = 0x23, + SOCKS5_HS_UNREACHABLE = 0x24, } socks5_reply_status_t; /* ===== Insecure rng */ diff --git a/src/or/or.h b/src/or/or.h index 3a53e5ed8..9d6445e5d 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -623,6 +623,11 @@ typedef enum { * you don't want to do that over a randomly chosen exit */ #define END_STREAM_REASON_PRIVATE_ADDR 262 +/* The connection the hidden service has failed because it was not found inside + * of any Hidden Service Directory Authority, or the connection to it failed. */ +#define END_STREAM_REASON_HS_NOT_FOUND 323 +#define END_STREAM_REASON_HS_UNREACHABLE 324 + /** Bitwise-and this value with endreason to mask out all flags. */ #define END_STREAM_REASON_MASK 511 diff --git a/src/or/reasons.c b/src/or/reasons.c index c51d8ee6f..8a8ef4f41 100644 --- a/src/or/reasons.c +++ b/src/or/reasons.c @@ -72,6 +72,8 @@ stream_end_reason_to_string(int reason) case END_STREAM_REASON_CONNRESET: return "connection reset"; case END_STREAM_REASON_TORPROTOCOL: return "Tor protocol error"; case END_STREAM_REASON_NOTDIRECTORY: return "not a directory"; + case END_STREAM_REASON_HS_NOT_FOUND: return "hidden service not found"; + case END_STREAM_REASON_HS_UNREACHABLE: return "hidden service not reachable"; default: log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Reason for ending (%d) not recognized.",reason); @@ -130,6 +132,12 @@ stream_end_reason_to_socks5_response(int reason) case END_STREAM_REASON_PRIVATE_ADDR: return SOCKS5_GENERAL_ERROR; + case END_STREAM_REASON_HS_NOT_FOUND: + return SOCKS5_HS_NOT_FOUND; + case END_STREAM_REASON_HS_UNREACHABLE: + return SOCKS5_HS_UNREACHABLE; + + default: log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Reason for ending (%d) not recognized; " diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 6c751be27..b96624944 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -668,6 +668,7 @@ rend_client_refetch_v2_renddesc(const rend_data_t *rend_query) log_info(LD_REND, "Could not pick one of the responsible hidden " "service directories to fetch descriptors, because " "we already tried them all unsuccessfully."); + /* Close pending connections. */ rend_client_desc_trynow(rend_query->onion_address); return; @@ -940,8 +941,8 @@ rend_client_desc_trynow(const char *query) if (rend_cmp_service_ids(query, rend_data->onion_address)) continue; assert_connection_ok(base_conn, now); - if (rend_cache_lookup_entry(rend_data->onion_address, -1, - &entry) == 1 && + rend_cache_lookup_entry(rend_data->onion_address, -1, &entry); + if (entry != NULL && rend_client_any_intro_points_usable(entry)) { /* either this fetch worked, or it failed but there was a * valid entry from before which we should reuse */ @@ -960,11 +961,27 @@ rend_client_desc_trynow(const char *query) if (!base_conn->marked_for_close) connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH); } - } else { /* 404, or fetch didn't get that far */ + } else if (entry == NULL) { + /* We couldn't get a descriptor for this HS at all; maybe it + * doesn't exist. */ + + log_notice(LD_REND,"Closing stream for '%s.onion': hidden service was " + "not found (no descriptors for it found).", + safe_str_client(query)); + + connection_mark_unattached_ap(conn, END_STREAM_REASON_HS_NOT_FOUND); + rend_client_note_connection_attempt_ended(query); + + } else { + /* We got a descriptor, but either (a) the HS published no intro points + * (i.e. it was shut down cleanly) or (b) we tried all the intro points + * it listed, and they failed. */ + log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is " "unavailable (try again later).", safe_str_client(query)); - connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED); + + connection_mark_unattached_ap(conn, END_STREAM_REASON_HS_UNREACHABLE); rend_client_note_connection_attempt_ended(query); } } SMARTLIST_FOREACH_END(base_conn); diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c index 4ef84f491..e24fbbdda 100644 --- a/src/tools/tor-resolve.c +++ b/src/tools/tor-resolve.c @@ -167,6 +167,10 @@ socks5_reason_to_string(char reason) return "command not supported"; case SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED: return "address type not supported"; + case SOCKS5_HS_NOT_FOUND: + return "hidden service not found"; + case SOCKS5_HS_UNREACHABLE: + return "hidden service unreachable"; default: return "unknown SOCKS5 code"; } -- cgit v1.2.1