diff --git a/src/core/or/circuitlist.c b/src/core/or/circuitlist.c index 9a0b9241da..3ae482a5b2 100644 --- a/src/core/or/circuitlist.c +++ b/src/core/or/circuitlist.c @@ -2343,43 +2343,6 @@ circuit_about_to_free(circuit_t *circ) orig_reason); } - if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) { - origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); - int timed_out = (reason == END_CIRC_REASON_TIMEOUT); - tor_assert(circ->state == CIRCUIT_STATE_OPEN); - tor_assert(ocirc->build_state->chosen_exit); - if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT && - 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(rend_data_get_address(ocirc->rend_data)), - 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) { - if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT && - 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(rend_data_get_address(ocirc->rend_data)), - 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/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c index 9d21acf42f..1a3767ce62 100644 --- a/src/feature/hs/hs_circuit.c +++ b/src/feature/hs/hs_circuit.c @@ -25,6 +25,7 @@ #include "feature/nodelist/describe.h" #include "feature/nodelist/nodelist.h" #include "feature/rend/rendservice.h" +#include "feature/rend/rendclient.h" #include "feature/stats/rephist.h" #include "lib/crypt_ops/crypto_dh.h" #include "lib/crypt_ops/crypto_rand.h" @@ -1205,6 +1206,15 @@ hs_circ_cleanup(circuit_t *circ) { tor_assert(circ); + /* v2 specific circuits. */ + if (circuit_is_hs_v2(circ)) { + if (circuit_is_hs_client(circ)) { + rend_client_circuit_cleanup(circ); + } + } + + /* From this point on, it is v3 specific. */ + /* If it's a service-side intro circ, notify the HS subsystem for the intro * point circuit closing so it can be dealt with cleanly. */ if (circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO || diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c index 6f4ee8b8c1..9718398255 100644 --- a/src/feature/rend/rendclient.c +++ b/src/feature/rend/rendclient.c @@ -1250,3 +1250,51 @@ rend_parse_service_authorization(const or_options_t *options, } return res; } + +/** The given circuit is being freed. Take appropriate action if it is of + * interest to the client subsystem. */ +void +rend_client_circuit_cleanup(circuit_t *circ) +{ + int reason = circ->marked_for_close_reason; + int orig_reason = circ->marked_for_close_orig_reason; + + tor_assert(circ); + + if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) { + origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); + int timed_out = (reason == END_CIRC_REASON_TIMEOUT); + tor_assert(circ->state == CIRCUIT_STATE_OPEN); + tor_assert(ocirc->build_state->chosen_exit); + if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT && + 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(rend_data_get_address(ocirc->rend_data)), + 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) { + if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT && + 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(rend_data_get_address(ocirc->rend_data)), + 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); + } + } + } +} diff --git a/src/feature/rend/rendclient.h b/src/feature/rend/rendclient.h index e5f333238e..dd9fa61ce9 100644 --- a/src/feature/rend/rendclient.h +++ b/src/feature/rend/rendclient.h @@ -47,5 +47,7 @@ rend_service_authorization_t *rend_client_lookup_service_authorization( const char *onion_address); void rend_service_authorization_free_all(void); +void rend_client_circuit_cleanup(circuit_t *circ); + #endif /* !defined(TOR_RENDCLIENT_H) */