From 4d7a45410d37cbc8c5b836f68b2fb7ae277280e1 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Fri, 4 Apr 2014 00:50:52 +0100 Subject: Fix the path overlapping problem Retry connecting to introduction points --- src/or/circuitbuild.c | 2 -- src/or/rendservice.c | 82 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 5f0271777..0fd7a80cc 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -2162,9 +2162,7 @@ extend_info_free(extend_info_t *info) { if (!info) return; - log_debug(LD_REND, "calling crypto_pk_free"); crypto_pk_free(info->onion_key); - log_debug(LD_REND, "calling tor_free"); tor_free(info); } diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 41b0a3b5d..b6d0fd38b 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -2433,6 +2433,19 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) "circuit, but we already have enough. Redefining purpose to " "general; leaving as internal."); + /* Remove the introduction point from the service + */ + { + rend_intro_point_t *intro = find_intro_point(circuit); + + rend_service_note_removing_intro_point(service, intro); + + smartlist_remove(service->intro_nodes, intro); + rend_intro_point_free(intro); + + intro = NULL; + } + circuit_change_purpose(TO_CIRCUIT(circuit), CIRCUIT_PURPOSE_C_GENERAL); { @@ -3074,27 +3087,56 @@ rend_services_introduce(void) node = node_get_by_id(intro->extend_info->identity_digest); if (!node || !intro_circ) { - int removing_this_intro_point_changes_the_intro_point_set = 1; - log_info(LD_REND, "Giving up on %s as intro point for %s" - " (circuit disappeared).", - safe_str_client(extend_info_describe(intro->extend_info)), - safe_str_client(service->service_id)); - rend_service_note_removing_intro_point(service, intro); - if (intro->time_expiring != -1) { - log_info(LD_REND, "We were already expiring the intro point; " - "no need to mark the HS descriptor as dirty over this."); - removing_this_intro_point_changes_the_intro_point_set = 0; - } else if (intro->listed_in_last_desc) { - log_info(LD_REND, "The intro point we are giving up on was " - "included in the last published descriptor. " - "Marking current descriptor as dirty."); - service->desc_is_dirty = now; + /* The introduction point could still be up, so attempt to reconnect + * before discounting it */ + + if (intro->unreachable_count >= 2) { + int removing_this_intro_point_changes_the_intro_point_set = 1; + + log_info(LD_REND, "Giving up on %s as intro point for %s" + " (circuit disappeared).", + safe_str_client(extend_info_describe(intro->extend_info)), + safe_str_client(service->service_id)); + + rend_service_note_removing_intro_point(service, intro); + + if (intro->time_expiring != -1) { + log_info(LD_REND, "We were already expiring the intro point; " + "no need to mark the HS descriptor as dirty over this."); + removing_this_intro_point_changes_the_intro_point_set = 0; + } else if (intro->listed_in_last_desc) { + log_info(LD_REND, "The intro point we are giving up on was " + "included in the last published descriptor. " + "Marking current descriptor as dirty."); + service->desc_is_dirty = now; + } + + rend_intro_point_free(intro); + intro = NULL; /* SMARTLIST_DEL_CURRENT takes a name, not a value. */ + SMARTLIST_DEL_CURRENT(service->intro_nodes, intro); + if (removing_this_intro_point_changes_the_intro_point_set) + intro_point_set_changed = 1; + } else { + if (intro->unreachable_count == 0) { + log_info(LD_REND, "Circuit to %s has disapeared", + safe_str_client(extend_info_describe(intro->extend_info))); + } + + intro->unreachable_count++; + log_info(LD_REND, "incremented unreachable_count for %s to %d)", + safe_str_client(extend_info_describe(intro->extend_info)), + intro->unreachable_count); + + log_info(LD_REND, "launching another circuit to %s", + safe_str_client(extend_info_describe(intro->extend_info))); + + r = rend_service_launch_establish_intro(service, intro); + if (r<0) { + log_warn(LD_REND, "Error launching circuit to node %s for service %s.", + safe_str_client(extend_info_describe(intro->extend_info)), + safe_str_client(service->service_id)); + } } - rend_intro_point_free(intro); - intro = NULL; /* SMARTLIST_DEL_CURRENT takes a name, not a value. */ - SMARTLIST_DEL_CURRENT(service->intro_nodes, intro); - if (removing_this_intro_point_changes_the_intro_point_set) - intro_point_set_changed = 1; } if (intro != NULL && intro_point_should_expire_now(intro, now)) { -- cgit v1.2.3