diff --git a/changes/bug13698 b/changes/bug13698 new file mode 100644 index 0000000000..9af22345b8 --- /dev/null +++ b/changes/bug13698 @@ -0,0 +1,6 @@ + o Major bugfixes: + - When closing an introduction circuit that was opened in + parallel, don't mark the introduction point as + unreachable. Previously, the first successful connection to an + introduction point would make the other uintroduction points get + marked as having timed out. Fixes bug 13698; bugfix on 0.0.6rc2. diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index d9da1e7f88..1b4582ad95 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -1719,30 +1719,35 @@ circuit_mark_for_close_, (circuit_t *circ, int reason, int line, tor_assert(circ->state == CIRCUIT_STATE_OPEN); tor_assert(ocirc->build_state->chosen_exit); tor_assert(ocirc->rend_data); - /* treat this like getting a nack from it */ - log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). %s", - safe_str_client(ocirc->rend_data->onion_address), - safe_str_client(build_state_get_exit_nickname(ocirc->build_state)), - timed_out ? "Recording timeout." : "Removing from descriptor."); - rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit, - ocirc->rend_data, - timed_out ? - INTRO_POINT_FAILURE_TIMEOUT : - INTRO_POINT_FAILURE_GENERIC); + if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT) { + /* treat this like getting a nack from it */ + log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). %s", + safe_str_client(ocirc->rend_data->onion_address), + safe_str_client(build_state_get_exit_nickname(ocirc->build_state)), + timed_out ? "Recording timeout." : "Removing from descriptor."); + rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit, + ocirc->rend_data, + timed_out ? + INTRO_POINT_FAILURE_TIMEOUT : + INTRO_POINT_FAILURE_GENERIC); + } } else if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCING && reason != END_CIRC_REASON_TIMEOUT) { origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); if (ocirc->build_state->chosen_exit && 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 (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT) { + 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_chan) { circuit_clear_cell_queue(circ, circ->n_chan); /* Only send destroy if the channel isn't closing anyway */ diff --git a/src/or/or.h b/src/or/or.h index b95bfb15a9..524f99daab 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -676,6 +676,10 @@ typedef enum { /* Negative reasons are internal: we never send them in a DESTROY or TRUNCATE * call; they only go to the controller for tracking */ + +/* Closing introduction point that were opened in parallel. */ +#define END_CIRC_REASON_IP_NOW_REDUNDANT -4 + /** Our post-timeout circuit time measurement period expired. * We must give up now */ #define END_CIRC_REASON_MEASUREMENT_EXPIRED -3 diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 10d13a37bb..5e5a09e41f 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -370,8 +370,7 @@ rend_client_rendcirc_has_opened(origin_circuit_t *circ) } /** - * Called to close other intro circuits we launched in parallel - * due to timeout. + * Called to close other intro circuits we launched in parallel. */ static void rend_client_close_other_intros(const char *onion_address) @@ -388,7 +387,7 @@ rend_client_close_other_intros(const char *onion_address) log_info(LD_REND|LD_CIRC, "Closing introduction circuit %d that we " "built in parallel (Purpose %d).", oc->global_identifier, c->purpose); - circuit_mark_for_close(c, END_CIRC_REASON_TIMEOUT); + circuit_mark_for_close(c, END_CIRC_REASON_IP_NOW_REDUNDANT); } } }