[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Detect and remove unreachable intro points
commit fbea8c8ef1e2f549e84ee681a9640c3006f7ad64
Author: Robert Ransom <rransom.8774@xxxxxxxxx>
Date: Sat Sep 17 03:53:07 2011 -0700
Detect and remove unreachable intro points
---
changes/bug3825a | 8 ++++++++
src/or/circuitlist.c | 16 ++++++++++++++++
src/or/or.h | 10 ++++++++++
src/or/rendclient.c | 19 +++++++++++++++++++
src/or/rendclient.h | 1 +
5 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/changes/bug3825a b/changes/bug3825a
new file mode 100644
index 0000000..6606e36
--- /dev/null
+++ b/changes/bug3825a
@@ -0,0 +1,8 @@
+ o Major bugfixes:
+
+ - When one of a hidden service's introduction points appears to be
+ unreachable, stop trying it. Previously, we would keep trying
+ to build circuits to the introduction point until we lost the
+ descriptor, usually because the user gave up and restarted Tor.
+ Partly fixes bug 3825.
+
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 2fc645a..b25a71e 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1121,6 +1121,9 @@ circuit_expire_all_dirty_circs(void)
* to note stats.
* - If purpose is C_INTRODUCE_ACK_WAIT, report the intro point
* failure we just had to the hidden service client module.
+ * - If purpose is C_INTRODUCING and <b>reason</b> isn't TIMEOUT,
+ * report to the hidden service client module that the intro point
+ * we just tried may be unreachable.
* - Send appropriate destroys and edge_destroys for conns and
* streams attached to circ.
* - If circ->rend_splice is set (we are the midpoint of a joined
@@ -1203,6 +1206,19 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
timed_out ?
INTRO_POINT_FAILURE_TIMEOUT :
INTRO_POINT_FAILURE_GENERIC);
+ } else if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCING &&
+ reason != END_STREAM_REASON_TIMEOUT) {
+ origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ tor_assert(ocirc->build_state->chosen_exit);
+ tor_assert(ocirc->rend_data);
+ log_info(LD_REND, "Failed intro circ %s to %s "
+ "(building circuit to intro point). "
+ "Marking intro point as possibly unreachable.",
+ safe_str_client(ocirc->rend_data->onion_address),
+ safe_str_client(build_state_get_exit_nickname(ocirc->build_state)));
+ rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit,
+ ocirc->rend_data,
+ INTRO_POINT_FAILURE_UNREACHABLE);
}
if (circ->n_conn) {
circuit_clear_cell_queue(circ, circ->n_conn);
diff --git a/src/or/or.h b/src/or/or.h
index 32d4b11..f884c12 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3456,6 +3456,11 @@ typedef struct rend_encoded_v2_service_descriptor_t {
char *desc_str; /**< Descriptor string. */
} rend_encoded_v2_service_descriptor_t;
+/** The maximum number of non-circuit-build-timeout failures a hidden
+ * service client will tolerate while trying to build a circuit to an
+ * introduction point. See also rend_intro_point_t.unreachable_count. */
+#define MAX_INTRO_POINT_REACHABILITY_FAILURES 5
+
/** Introduction point information. Used both in rend_service_t (on
* the service side) and in rend_service_descriptor_t (on both the
* client and service side). */
@@ -3470,6 +3475,11 @@ typedef struct rend_intro_point_t {
* hidden service connection attempt, but it may be tried again
* during a future connection attempt. */
unsigned int timed_out : 1;
+
+ /** (Client side only) The number of times we have failed to build a
+ * circuit to this intro point for some reason other than our
+ * circuit-build timeout. See also MAX_INTRO_POINT_REACHABILITY_FAILURES. */
+ unsigned int unreachable_count : 3;
} rend_intro_point_t;
/** Information used to connect to a hidden service. Used on both the
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 3c1c116..0a9e2a6 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -662,6 +662,11 @@ rend_client_cancel_descriptor_fetches(void)
* current hidden service connection attempt has ended or it has
* appeared in a newly fetched rendezvous descriptor.
*
+ * If <b>failure_type</b> is INTRO_POINT_FAILURE_UNREACHABLE,
+ * increment the intro point's reachability-failure count; if it has
+ * now failed MAX_INTRO_POINT_REACHABILITY_FAILURES or more times,
+ * remove the intro point from (our parsed copy of) the HS descriptor.
+ *
* Return -1 if error, 0 if no usable intro points remain or service
* unrecognized, 1 if recognized and some intro points remain.
*/
@@ -704,6 +709,20 @@ rend_client_report_intro_point_failure(extend_info_t *failed_intro,
case INTRO_POINT_FAILURE_TIMEOUT:
intro->timed_out = 1;
break;
+ case INTRO_POINT_FAILURE_UNREACHABLE:
+ ++(intro->unreachable_count);
+ {
+ int zap_intro_point =
+ intro->unreachable_count >= MAX_INTRO_POINT_REACHABILITY_FAILURES;
+ log_info(LD_REND, "Failed to reach this intro point %u times.%s",
+ intro->unreachable_count,
+ zap_intro_point ? " Removing from descriptor.": "");
+ if (zap_intro_point) {
+ rend_intro_point_free(intro);
+ smartlist_del(ent->parsed->intro_nodes, i);
+ }
+ }
+ break;
}
break;
}
diff --git a/src/or/rendclient.h b/src/or/rendclient.h
index 46779b7..d87cb1f 100644
--- a/src/or/rendclient.h
+++ b/src/or/rendclient.h
@@ -25,6 +25,7 @@ void rend_client_purge_last_hid_serv_requests(void);
#define INTRO_POINT_FAILURE_GENERIC 0
#define INTRO_POINT_FAILURE_TIMEOUT 1
+#define INTRO_POINT_FAILURE_UNREACHABLE 2
int rend_client_report_intro_point_failure(extend_info_t *failed_intro,
const rend_data_t *rend_query,
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits