hs: Collect rendezvous circuit metrics

The total number of rendezvous circuit created and the number of established
ones which is a gauge that decreases to keep an updated counter.

Related to #40063

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
David Goulet 2020-10-20 14:59:44 -04:00
parent 2fe0322fe4
commit c081bee38a
6 changed files with 70 additions and 0 deletions

View File

@ -24,6 +24,7 @@
#include "feature/hs/hs_circuitmap.h" #include "feature/hs/hs_circuitmap.h"
#include "feature/hs/hs_client.h" #include "feature/hs/hs_client.h"
#include "feature/hs/hs_ident.h" #include "feature/hs/hs_ident.h"
#include "feature/hs/hs_metrics.h"
#include "feature/hs/hs_service.h" #include "feature/hs/hs_service.h"
#include "feature/nodelist/describe.h" #include "feature/nodelist/describe.h"
#include "feature/nodelist/nodelist.h" #include "feature/nodelist/nodelist.h"
@ -429,6 +430,9 @@ launch_rendezvous_point_circuit,(const hs_service_t *service,
safe_str_client(service->onion_address)); safe_str_client(service->onion_address));
goto end; goto end;
} }
/* Update metrics with this new rendezvous circuit launched. */
hs_metrics_new_rdv(&service->keys.identity_pk);
log_info(LD_REND, "Rendezvous circuit launched to %s with cookie %s " log_info(LD_REND, "Rendezvous circuit launched to %s with cookie %s "
"for %s service %s", "for %s service %s",
safe_str_client(extend_info_describe(info)), safe_str_client(extend_info_describe(info)),
@ -1312,6 +1316,12 @@ hs_circ_cleanup_on_close(circuit_t *circ)
cleanup_on_close_client_circ(circ); cleanup_on_close_client_circ(circ);
} }
if (circuit_purpose_is_hs_service(circ->purpose)) {
if (circuit_is_hs_v3(circ)) {
hs_service_circuit_cleanup_on_close(circ);
}
}
/* On close, we simply remove it from the circuit map. It can not be used /* On close, we simply remove it from the circuit map. It can not be used
* anymore. We keep this code path fast and lean. */ * anymore. We keep this code path fast and lean. */

View File

@ -43,4 +43,18 @@ void hs_metrics_update_by_service(const hs_metrics_key_t key,
#define hs_metrics_app_read_bytes(i, port, n) \ #define hs_metrics_app_read_bytes(i, port, n) \
hs_metrics_update_by_ident(HS_METRICS_APP_READ_BYTES, (i), (port), (n)) hs_metrics_update_by_ident(HS_METRICS_APP_READ_BYTES, (i), (port), (n))
/** Newly established rendezvous. This is called as soon as the circuit purpose
* is REND_JOINED which is when the RENDEZVOUS2 cell is sent. */
#define hs_metrics_new_established_rdv(s) \
hs_metrics_update_by_service(HS_METRICS_NUM_ESTABLISHED_RDV, (s), 0, 1)
/** Established rendezvous closed. This is called when the circuit in
* REND_JOINED state is marked for close. */
#define hs_metrics_close_established_rdv(i) \
hs_metrics_update_by_ident(HS_METRICS_NUM_ESTABLISHED_RDV, (i), 0, -1)
/** New rendezvous circuit being launched. */
#define hs_metrics_new_rdv(i) \
hs_metrics_update_by_ident(HS_METRICS_NUM_RDV, (i), 0, 1)
#endif /* !defined(TOR_FEATURE_HS_HS_METRICS_H) */ #endif /* !defined(TOR_FEATURE_HS_HS_METRICS_H) */

View File

@ -41,6 +41,18 @@ const hs_metrics_entry_t base_metrics[] =
.help = "Total number of bytes read from the application", .help = "Total number of bytes read from the application",
.port_as_label = true, .port_as_label = true,
}, },
{
.key = HS_METRICS_NUM_ESTABLISHED_RDV,
.type = METRICS_TYPE_GAUGE,
.name = "hs_rdv_established_count",
.help = "Total number of established rendezvous circuit",
},
{
.key = HS_METRICS_NUM_RDV,
.type = METRICS_TYPE_COUNTER,
.name = "hs_rdv_num_total",
.help = "Total number of rendezvous circuit created",
},
}; };
/** Size of base_metrics array that is number of entries. */ /** Size of base_metrics array that is number of entries. */

View File

@ -21,6 +21,10 @@ typedef enum {
HS_METRICS_APP_WRITE_BYTES = 1, HS_METRICS_APP_WRITE_BYTES = 1,
/** Number of bytes read from application to onion service. */ /** Number of bytes read from application to onion service. */
HS_METRICS_APP_READ_BYTES = 2, HS_METRICS_APP_READ_BYTES = 2,
/** Number of established rendezsvous. */
HS_METRICS_NUM_ESTABLISHED_RDV = 3,
/** Number of rendezsvous circuits created. */
HS_METRICS_NUM_RDV = 4,
} hs_metrics_key_t; } hs_metrics_key_t;
/** The metadata of an HS metrics. */ /** The metadata of an HS metrics. */

View File

@ -3391,6 +3391,15 @@ service_rendezvous_circ_has_opened(origin_circuit_t *circ)
/* If the cell can't be sent, the circuit will be closed within this /* If the cell can't be sent, the circuit will be closed within this
* function. */ * function. */
hs_circ_service_rp_has_opened(service, circ); hs_circ_service_rp_has_opened(service, circ);
/* Update metrics that we have an established rendezvous circuit. It is not
* entirely true until the client receives the RENDEZVOUS2 cell and starts
* sending but if that circuit collapes, we'll decrement the counter thus it
* will even out the metric. */
if (TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) {
hs_metrics_new_established_rdv(service);
}
goto done; goto done;
err: err:
@ -3579,6 +3588,26 @@ service_encode_descriptor(const hs_service_t *service,
/* Public API */ /* Public API */
/* ========== */ /* ========== */
/** Called when a circuit was just cleaned up. This is done right before the
* circuit is marked for close. */
void
hs_service_circuit_cleanup_on_close(const circuit_t *circ)
{
tor_assert(circ);
tor_assert(CIRCUIT_IS_ORIGIN(circ));
switch (circ->purpose) {
case CIRCUIT_PURPOSE_S_REND_JOINED:
/* About to close an established rendezvous circuit. Update the metrics to
* reflect how many we have at the moment. */
hs_metrics_close_established_rdv(
&CONST_TO_ORIGIN_CIRCUIT(circ)->hs_ident->identity_pk);
break;
default:
break;
}
}
/** This is called everytime the service map (v2 or v3) changes that is if an /** This is called everytime the service map (v2 or v3) changes that is if an
* element is added or removed. */ * element is added or removed. */
void void

View File

@ -386,6 +386,7 @@ hs_circuit_id_protocol_t
hs_service_exports_circuit_id(const ed25519_public_key_t *pk); hs_service_exports_circuit_id(const ed25519_public_key_t *pk);
void hs_service_dump_stats(int severity); void hs_service_dump_stats(int severity);
void hs_service_circuit_cleanup_on_close(const circuit_t *circ);
#ifdef HS_SERVICE_PRIVATE #ifdef HS_SERVICE_PRIVATE