mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
prop224: Add a circuit has closed callback
When the circuit is about to be freed which has been marked close before, for introduction circuit we now call this has_closed() callback so we can cleanup any introduction point that have retried to many times or at least flag them that their circuit is not established anymore. Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
4a8cf17897
commit
15864a1b70
@ -1949,6 +1949,13 @@ circuit_about_to_free(circuit_t *circ)
|
||||
orig_reason);
|
||||
}
|
||||
|
||||
/* Notify the HS subsystem for any intro point circuit closing so it can be
|
||||
* dealt with cleanly. */
|
||||
if (circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
|
||||
circ->purpose == CIRCUIT_PURPOSE_S_INTRO) {
|
||||
hs_service_intro_circ_has_closed(TO_ORIGIN_CIRCUIT(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);
|
||||
|
@ -1584,18 +1584,10 @@ cleanup_intro_points(hs_service_t *service, time_t now)
|
||||
* node_t anymore (removed from our latest consensus) or if we've
|
||||
* reached the maximum number of retry with a non existing circuit. */
|
||||
if (has_expired || node == NULL ||
|
||||
(ocirc == NULL &&
|
||||
ip->circuit_retries > MAX_INTRO_POINT_CIRCUIT_RETRIES)) {
|
||||
ip->circuit_retries > MAX_INTRO_POINT_CIRCUIT_RETRIES) {
|
||||
/* Remove intro point from descriptor map. We'll add it to the failed
|
||||
* map if we retried it too many times. */
|
||||
MAP_DEL_CURRENT(key);
|
||||
|
||||
/* We've retried too many times, remember it has a failed intro point
|
||||
* so we don't pick it up again. It will be retried in
|
||||
* INTRO_CIRC_RETRY_PERIOD seconds. */
|
||||
if (ip->circuit_retries >= MAX_INTRO_POINT_CIRCUIT_RETRIES) {
|
||||
remember_failing_intro_point(ip, desc, now);
|
||||
}
|
||||
service_intro_point_free(ip);
|
||||
|
||||
/* XXX: Legacy code does NOT do that, it keeps the circuit open until
|
||||
@ -1611,11 +1603,6 @@ cleanup_intro_points(hs_service_t *service, time_t now)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (ocirc == NULL) {
|
||||
/* Circuit disappeared so make sure the intro point is updated. By
|
||||
* keeping the object in the descriptor, we'll be able to retry. */
|
||||
ip->circuit_established = 0;
|
||||
}
|
||||
} DIGEST256MAP_FOREACH_END;
|
||||
} FOR_EACH_DESCRIPTOR_END;
|
||||
}
|
||||
@ -2386,6 +2373,55 @@ service_add_fnames_to_list(const hs_service_t *service, smartlist_t *list)
|
||||
/* Public API */
|
||||
/* ========== */
|
||||
|
||||
/* Called once an introduction circuit is closed. If the circuit doesn't have
|
||||
* a v3 identifier, it is ignored. */
|
||||
void
|
||||
hs_service_intro_circ_has_closed(origin_circuit_t *circ)
|
||||
{
|
||||
hs_service_t *service = NULL;
|
||||
hs_service_intro_point_t *ip = NULL;
|
||||
hs_service_descriptor_t *desc = NULL;
|
||||
|
||||
tor_assert(circ);
|
||||
|
||||
if (circ->hs_ident == NULL) {
|
||||
/* This is not a v3 circuit, ignore. */
|
||||
goto end;
|
||||
}
|
||||
|
||||
get_objects_from_ident(circ->hs_ident, &service, &ip, &desc);
|
||||
if (service == NULL) {
|
||||
log_warn(LD_REND, "Unable to find any hidden service associated "
|
||||
"identity key %s on intro circuit %u.",
|
||||
ed25519_fmt(&circ->hs_ident->identity_pk),
|
||||
TO_CIRCUIT(circ)->n_circ_id);
|
||||
goto end;
|
||||
}
|
||||
if (ip == NULL) {
|
||||
/* The introduction point object has already been removed probably by our
|
||||
* cleanup process so ignore. */
|
||||
goto end;
|
||||
}
|
||||
/* Can't have an intro point object without a descriptor. */
|
||||
tor_assert(desc);
|
||||
|
||||
/* Circuit disappeared so make sure the intro point is updated. By
|
||||
* keeping the object in the descriptor, we'll be able to retry. */
|
||||
ip->circuit_established = 0;
|
||||
|
||||
/* We've retried too many times, remember it as a failed intro point so we
|
||||
* don't pick it up again. It will be retried in INTRO_CIRC_RETRY_PERIOD
|
||||
* seconds. */
|
||||
if (ip->circuit_retries > MAX_INTRO_POINT_CIRCUIT_RETRIES) {
|
||||
remember_failing_intro_point(ip, desc, approx_time());
|
||||
service_intro_point_remove(service, ip);
|
||||
service_intro_point_free(ip);
|
||||
}
|
||||
|
||||
end:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Given conn, a rendezvous edge connection acting as an exit stream, look up
|
||||
* the hidden service for the circuit circ, and look up the port and address
|
||||
* based on the connection port. Assign the actual connection address.
|
||||
|
@ -270,6 +270,8 @@ int hs_service_receive_introduce2(origin_circuit_t *circ,
|
||||
const uint8_t *payload,
|
||||
size_t payload_len);
|
||||
|
||||
void hs_service_intro_circ_has_closed(origin_circuit_t *circ);
|
||||
|
||||
#ifdef HS_SERVICE_PRIVATE
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
|
Loading…
Reference in New Issue
Block a user