#ifndef TOR_HS_SERVICE_H
#define TOR_HS_SERVICE_H
#include "lib/crypt_ops/crypto_curve25519.h"
#include "lib/crypt_ops/crypto_ed25519.h"
#include "lib/metrics/metrics_store.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_descriptor.h"
#include "feature/hs/hs_ident.h"
#include "feature/hs/hs_intropoint.h"
#include "feature/hs_common/replaycache.h"
#include "trunnel/hs/cell_establish_intro.h"
#include "ext/ht.h"
#define HS_SERVICE_DEFAULT_VERSION HS_VERSION_THREE
#define HS_SERVICE_NEXT_UPLOAD_TIME_MIN (60 * 60)
#define HS_SERVICE_NEXT_UPLOAD_TIME_MAX (120 * 60)
typedef struct hs_service_metrics_t {
metrics_store_t *store;
} hs_service_metrics_t;
typedef struct hs_service_intro_point_t {
hs_intropoint_t base;
curve25519_public_key_t onion_key;
ed25519_keypair_t auth_key_kp;
curve25519_keypair_t enc_key_kp;
crypto_pk_t *legacy_key;
uint8_t legacy_key_digest[DIGEST_LEN];
uint64_t introduce2_count;
uint64_t introduce2_max;
time_t time_to_expire;
uint32_t circuit_retries;
replaycache_t *replay_cache;
unsigned int support_intro2_dos_defense : 1;
} hs_service_intro_point_t;
typedef struct hs_service_intropoints_t {
time_t retry_period_started;
unsigned int num_circuits_launched;
digest256map_t *map;
digestmap_t *failed_id;
} hs_service_intropoints_t;
typedef struct hs_service_descriptor_t {
curve25519_keypair_t auth_ephemeral_kp;
uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
ed25519_keypair_t signing_kp;
ed25519_keypair_t blinded_kp;
uint64_t time_period_num;
struct crypto_ope_t *ope_cipher;
hs_descriptor_t *desc;
time_t next_upload_time;
hs_service_intropoints_t intro_points;
unsigned int missing_intro_points : 1;
smartlist_t *previous_hsdirs;
} hs_service_descriptor_t;
typedef struct hs_service_keys_t {
ed25519_public_key_t identity_pk;
ed25519_secret_key_t identity_sk;
unsigned int is_identify_key_offline : 1;
} hs_service_keys_t;
typedef struct hs_service_authorized_client_t {
curve25519_public_key_t client_pk;
} hs_service_authorized_client_t;
typedef enum {
HS_CIRCUIT_ID_PROTOCOL_NONE,
HS_CIRCUIT_ID_PROTOCOL_HAPROXY
} hs_circuit_id_protocol_t;
typedef struct hs_service_config_t {
uint32_t version;
unsigned int hs_version_explicitly_set : 1;
smartlist_t *ports;
char *directory_path;
uint64_t max_streams_per_rdv_circuit;
unsigned int max_streams_close_circuit : 1;
unsigned int num_intro_points;
unsigned int is_client_auth_enabled : 1;
smartlist_t *clients;
unsigned int allow_unknown_ports : 1;
unsigned int is_single_onion : 1;
unsigned int dir_group_readable : 1;
unsigned int is_ephemeral : 1;
hs_circuit_id_protocol_t circuit_id_protocol;
unsigned int has_dos_defense_enabled : 1;
uint32_t intro_dos_rate_per_sec;
uint32_t intro_dos_burst_per_sec;
smartlist_t *ob_master_pubkeys;
} hs_service_config_t;
typedef struct hs_service_state_t {
time_t intro_circ_retry_started_time;
unsigned int num_intro_circ_launched;
replaycache_t *replay_cache_rend_cookie;
time_t next_rotation_time;
hs_subcredential_t *ob_subcreds;
size_t n_ob_subcreds;
} hs_service_state_t;
typedef struct hs_service_t {
char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1];
HT_ENTRY(hs_service_t) hs_service_node;
hs_service_state_t state;
hs_service_keys_t keys;
hs_service_config_t config;
hs_service_descriptor_t *desc_current;
hs_service_descriptor_t *desc_next;
hs_service_metrics_t metrics;
} hs_service_t;
typedef HT_HEAD(hs_service_ht, hs_service_t) hs_service_ht;
void hs_service_init(void);
void hs_service_free_all(void);
hs_service_t *hs_service_new(const or_options_t *options);
void hs_service_free_(hs_service_t *service);
#define hs_service_free(s) FREE_AND_NULL(hs_service_t, hs_service_free_, (s))
hs_service_t *hs_service_find(const ed25519_public_key_t *ident_pk);
MOCK_DECL(unsigned int, hs_service_get_num_services,(void));
void hs_service_stage_services(const smartlist_t *service_list);
int hs_service_load_all_keys(void);
int hs_service_get_version_from_key(const hs_service_t *service);
void hs_service_lists_fnames_for_sandbox(smartlist_t *file_list,
smartlist_t *dir_list);
int hs_service_set_conn_addr_port(const origin_circuit_t *circ,
edge_connection_t *conn);
smartlist_t *hs_service_get_metrics_stores(void);
void hs_service_map_has_changed(void);
void hs_service_dir_info_changed(void);
void hs_service_run_scheduled_events(time_t now);
void hs_service_circuit_has_opened(origin_circuit_t *circ);
int hs_service_receive_intro_established(origin_circuit_t *circ,
const uint8_t *payload,
size_t payload_len);
int hs_service_receive_introduce2(origin_circuit_t *circ,
const uint8_t *payload,
size_t payload_len);
char *hs_service_lookup_current_desc(const ed25519_public_key_t *pk);
hs_service_add_ephemeral_status_t
hs_service_add_ephemeral(ed25519_secret_key_t *sk, smartlist_t *ports,
int max_streams_per_rdv_circuit,
int max_streams_close_circuit, char **address_out);
int hs_service_del_ephemeral(const char *address);
void hs_service_upload_desc_to_dir(const char *encoded_desc,
const uint8_t version,
const ed25519_public_key_t *identity_pk,
const ed25519_public_key_t *blinded_pk,
const routerstatus_t *hsdir_rs);
hs_circuit_id_protocol_t
hs_service_exports_circuit_id(const ed25519_public_key_t *pk);
void hs_service_dump_stats(int severity);
void hs_service_circuit_cleanup_on_close(const circuit_t *circ);
#ifdef HS_SERVICE_PRIVATE
#ifdef TOR_UNIT_TESTS
STATIC unsigned int get_hs_service_map_size(void);
STATIC int get_hs_service_staging_list_size(void);
STATIC hs_service_ht *get_hs_service_map(void);
STATIC hs_service_t *get_first_service(void);
STATIC hs_service_intro_point_t *service_intro_point_find_by_ident(
const hs_service_t *service,
const hs_ident_circuit_t *ident);
MOCK_DECL(STATIC unsigned int, count_desc_circuit_established,
(const hs_service_descriptor_t *desc));
#endif
STATIC hs_service_t *find_service(hs_service_ht *map,
const ed25519_public_key_t *pk);
STATIC void remove_service(hs_service_ht *map, hs_service_t *service);
STATIC int register_service(hs_service_ht *map, hs_service_t *service);
STATIC hs_service_intro_point_t *service_intro_point_new(const node_t *node);
STATIC void service_intro_point_free_(hs_service_intro_point_t *ip);
#define service_intro_point_free(ip) \
FREE_AND_NULL(hs_service_intro_point_t, \
service_intro_point_free_, (ip))
STATIC void service_intro_point_add(digest256map_t *map,
hs_service_intro_point_t *ip);
STATIC void service_intro_point_remove(const hs_service_t *service,
const hs_service_intro_point_t *ip);
STATIC hs_service_intro_point_t *service_intro_point_find(
const hs_service_t *service,
const ed25519_public_key_t *auth_key);
STATIC hs_service_descriptor_t *service_descriptor_new(void);
STATIC hs_service_descriptor_t *service_desc_find_by_intro(
const hs_service_t *service,
const hs_service_intro_point_t *ip);
STATIC int client_filename_is_valid(const char *filename);
STATIC hs_service_authorized_client_t *
parse_authorized_client(const char *client_key_str);
STATIC void get_objects_from_ident(const hs_ident_circuit_t *ident,
hs_service_t **service,
hs_service_intro_point_t **ip,
hs_service_descriptor_t **desc);
STATIC const node_t *
get_node_from_intro_point(const hs_service_intro_point_t *ip);
STATIC int can_service_launch_intro_circuit(hs_service_t *service,
time_t now);
STATIC int intro_point_should_expire(const hs_service_intro_point_t *ip,
time_t now);
STATIC void run_housekeeping_event(time_t now);
STATIC void rotate_all_descriptors(time_t now);
STATIC void build_all_descriptors(time_t now);
STATIC void update_all_descriptors_intro_points(time_t now);
STATIC void run_upload_descriptor_event(time_t now);
STATIC void service_descriptor_free_(hs_service_descriptor_t *desc);
#define service_descriptor_free(d) \
FREE_AND_NULL(hs_service_descriptor_t, \
service_descriptor_free_, (d))
STATIC void
service_authorized_client_free_(hs_service_authorized_client_t *client);
#define service_authorized_client_free(c) \
FREE_AND_NULL(hs_service_authorized_client_t, \
service_authorized_client_free_, (c))
STATIC int
write_address_to_file(const hs_service_t *service, const char *fname_);
STATIC void upload_descriptor_to_all(const hs_service_t *service,
hs_service_descriptor_t *desc);
STATIC void service_desc_schedule_upload(hs_service_descriptor_t *desc,
time_t now,
int descriptor_changed);
STATIC int service_desc_hsdirs_changed(const hs_service_t *service,
const hs_service_descriptor_t *desc);
STATIC int service_authorized_client_config_equal(
const hs_service_config_t *config1,
const hs_service_config_t *config2);
STATIC void service_clear_config(hs_service_config_t *config);
#endif
#endif