#define HS_METRICS_ENTRY_PRIVATE
#include "orconfig.h"
#include "lib/malloc/malloc.h"
#include "lib/container/smartlist.h"
#include "lib/metrics/metrics_store.h"
#include "feature/hs/hs_metrics.h"
#include "feature/hs/hs_metrics_entry.h"
#include "feature/hs/hs_service.h"
static const char *
port_to_str(const uint16_t port)
{
static char buf[8];
tor_snprintf(buf, sizeof(buf), "%u", port);
return buf;
}
static const char *
format_label(const char *key, const char *value)
{
static char buf[128];
tor_snprintf(buf, sizeof(buf), "%s=%s", key, value);
return buf;
}
static void
init_store(hs_service_t *service)
{
metrics_store_t *store;
tor_assert(service);
store = service->metrics.store;
for (size_t i = 0; i < base_metrics_size; ++i) {
metrics_store_entry_t *entry =
metrics_store_add(store, base_metrics[i].type, base_metrics[i].name,
base_metrics[i].help);
metrics_store_entry_add_label(entry,
format_label("onion", service->onion_address));
if (base_metrics[i].port_as_label && service->config.ports) {
SMARTLIST_FOREACH_BEGIN(service->config.ports,
const rend_service_port_config_t *, p) {
metrics_store_entry_add_label(entry,
format_label("port", port_to_str(p->virtual_port)));
} SMARTLIST_FOREACH_END(p);
}
}
}
void
hs_metrics_update_by_service(const hs_metrics_key_t key,
hs_service_t *service, const uint16_t port,
int64_t n)
{
tor_assert(service);
smartlist_t *entries = metrics_store_get_all(service->metrics.store,
base_metrics[key].name);
if (BUG(!entries)) {
return;
}
SMARTLIST_FOREACH_BEGIN(entries, metrics_store_entry_t *, entry) {
if (port == 0 ||
metrics_store_entry_has_label(entry,
format_label("port", port_to_str(port)))) {
metrics_store_entry_update(entry, n);
break;
}
} SMARTLIST_FOREACH_END(entry);
}
void
hs_metrics_update_by_ident(const hs_metrics_key_t key,
const ed25519_public_key_t *ident_pk,
const uint16_t port, int64_t n)
{
hs_service_t *service;
tor_assert(ident_pk);
service = hs_service_find(ident_pk);
if (!service) {
return;
}
hs_metrics_update_by_service(key, service, port, n);
}
const smartlist_t *
hs_metrics_get_stores(void)
{
static smartlist_t *stores_list = NULL;
smartlist_free(stores_list);
stores_list = hs_service_get_metrics_stores();
return stores_list;
}
void
hs_metrics_service_init(hs_service_t *service)
{
tor_assert(service);
if (BUG(service->metrics.store)) {
return;
}
service->metrics.store = metrics_store_new();
init_store(service);
}
void
hs_metrics_service_free(hs_service_t *service)
{
tor_assert(service);
metrics_store_free(service->metrics.store);
}