8#define HS_CIRCUIT_PRIVATE
22#include "feature/client/circpathbias.h"
41#include "trunnel/ed25519_cert.h"
42#include "trunnel/hs/cell_establish_intro.h"
69 if (is_service_side) {
72 "HS e2e circuit setup with wrong purpose (%d)", circ_purpose);
77 if (!is_service_side) {
81 "Client e2e circuit setup with wrong purpose (%d)", circ_purpose);
99 uint8_t keys[HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN];
104 keys,
sizeof(keys)) < 0) {
110 cpath->magic = CRYPT_PATH_MAGIC;
113 is_service_side, 1) < 0) {
119 memwipe(keys, 0,
sizeof(keys));
133 int new_circ_purpose = is_service_side ?
138 hop->
state = CPATH_STATE_OPEN;
153 if (!is_service_side) {
177 unsigned int count = 0;
199 } DIGEST256MAP_FOREACH_END;
207 const uint8_t *rendezvous_cookie,
231 sizeof(handshake_info));
236 sizeof(keys->ntor_key_seed));
278 &service->
config, ip, payload);
280 log_warn(
LD_REND,
"Unable to encode ESTABLISH_INTRO cell for service %s "
281 "on circuit %u. Closing circuit.",
288 if (relay_send_command_from_edge(CONTROL_CELL_ID,
TO_CIRCUIT(circ),
289 RELAY_COMMAND_ESTABLISH_INTRO,
290 (
char *) payload, cell_len,
292 log_info(
LD_REND,
"Unable to send ESTABLISH_INTRO cell for service %s "
305 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
307 memwipe(payload, 0,
sizeof(payload));
315 return "single onion";
333 int circ_needs_uptime;
352 "Not enough info to open a circuit to a rendezvous point for "
361 if (circ_needs_uptime) {
381 log_warn(
LD_REND,
"Giving up on launching a rendezvous circuit to %s "
391 log_info(
LD_REND,
"Rendezvous circuit launched to %s with cookie %s "
394 safe_str_client(
hex_str((
const char *)
412 if (hs_ntor_service_get_rendezvous1_keys(ip_auth_pubkey,
419 log_info(
LD_REND,
"Unable to get RENDEZVOUS1 key material for "
422 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
427 &ephemeral_kp.pubkey, &keys);
428 memwipe(&ephemeral_kp, 0,
sizeof(ephemeral_kp));
429 memwipe(&keys, 0,
sizeof(keys));
447 extend_info_free(info);
471 log_info(
LD_REND,
"Attempt to build a rendezvous circuit to %s has "
472 "failed with %d attempts and expiry time %ld. "
473 "Giving up building.",
503 log_info(
LD_REND,
"Retrying rendezvous point circuit to %s",
520 if (new_circ == NULL) {
521 log_warn(
LD_REND,
"Failed to launch rendezvous circuit to %s",
525 HS_METRICS_ERR_RDV_RETRY);
573 rp_lspecs = node_get_link_specifier_smartlist(rp_node, 0);
574 if (smartlist_len(rp_lspecs) == 0) {
576 smartlist_free(rp_lspecs);
587 if (intro1_data->
onion_pk == NULL) {
633 if (a->rdv_data.
pow_effort > b->rdv_data.pow_effort) {
635 }
else if (a->rdv_data.
pow_effort == b->rdv_data.pow_effort) {
667 smartlist_t *old_pqueue = pow_state->rend_request_pqueue;
670 log_info(
LD_REND,
"Rendezvous request priority queue has "
671 "reached capacity (%d). Discarding the bottom half.",
672 smartlist_len(old_pqueue));
674 while (smartlist_len(old_pqueue) &&
675 smartlist_len(new_pqueue) < pow_state->pqueue_high_level/2) {
682 log_info(
LD_REND,
"While trimming, rend request has been pending "
683 "for too long; discarding.");
685 pow_state->max_trimmed_effort =
MAX(pow_state->max_trimmed_effort,
699 pow_state->max_trimmed_effort =
MAX(pow_state->max_trimmed_effort,
700 req->rdv_data.pow_effort);
702 } SMARTLIST_FOREACH_END(req);
703 smartlist_free(old_pqueue);
735 tor_assert(smartlist_len(pow_state->rend_request_pqueue));
738 smartlist_get(pow_state->rend_request_pqueue, 0);
740 if (req->rdv_data.
pow_effort >= pow_state->suggested_effort)
751 while (smartlist_len(pow_state->rend_request_pqueue)) {
761#define MAX_CHEAP_REND_CIRCUITS_IN_PROGRESS 16
768 time_t now = time(NULL);
773 log_info(
LD_REND,
"Considering launching more rendezvous responses. "
774 "%d in-flight, %d pending.",
776 smartlist_len(pow_state->rend_request_pqueue));
781 while (smartlist_len(pow_state->rend_request_pqueue) > 0) {
789 log_info(
LD_REND,
"Next request to launch is low priority, and "
790 "%d in-flight already. Waiting to launch more.", in_flight);
791 const struct timeval delay_tv = { 0, 100000 };
796 if (pow_state->using_pqueue_bucket) {
798 (uint32_t) monotime_coarse_absolute_sec());
800 if (token_bucket_ctr_get(&pow_state->pqueue_bucket) > 0) {
801 token_bucket_ctr_dec(&pow_state->pqueue_bucket, 1);
804 const struct timeval delay_tv = { 0, 100000 };
817 smartlist_len(pow_state->rend_request_pqueue));
819 log_info(
LD_REND,
"Dequeued pending rendezvous request with effort: %u. "
821 "Remaining requests: %u",
824 smartlist_len(pow_state->rend_request_pqueue));
827 log_info(
LD_REND,
"Top rend request has been pending for too long; "
828 "discarding and moving to the next one.");
835 &req->ip_enc_key_kp, &req->rdv_data, now);
838 ++pow_state->rend_handled;
845 if (smartlist_len(pow_state->rend_request_pqueue) > 0) {
848 if (smartlist_len(pow_state->rend_request_pqueue) >=
849 pow_state->pqueue_low_level) {
850 pow_state->had_queue = 1;
878 memcpy(&req->ip_enc_key_kp, &ip->
enc_key_kp,
sizeof(req->ip_enc_key_kp));
879 memcpy(&req->rdv_data, &data->
rdv_data,
sizeof(req->rdv_data));
892 smartlist_len(pow_state->rend_request_pqueue));
894 log_info(
LD_REND,
"Enqueued rendezvous request with effort: %u. "
895 "Queued requests: %u",
897 smartlist_len(pow_state->rend_request_pqueue));
900 if (pow_state->pop_pqueue_ev == NULL) {
901 pow_state->pop_pqueue_ev =
909 if (smartlist_len(pow_state->rend_request_pqueue) >=
910 pow_state->pqueue_high_level) {
913 smartlist_len(pow_state->rend_request_pqueue));
929 uint8_t sendme_inc,
bool is_single_onion)
947 if (is_single_onion) {
1051 log_info(
LD_REND,
"Launching a circuit to intro point %s for service %s.",
1089 unsigned int num_intro_circ, num_needed_circ;
1100 if (num_intro_circ > num_needed_circ) {
1109 log_info(
LD_CIRC |
LD_REND,
"Introduction circuit just opened but we "
1110 "have enough for service %s. Repurposing "
1111 "it to general and leaving internal.",
1117 hs_ident_circuit_free(circ->
hs_ident);
1133 log_info(
LD_REND,
"Introduction circuit %u established for service %s.",
1162 log_info(
LD_REND,
"Rendezvous circuit %u has opened with cookie %s "
1187 if (relay_send_command_from_edge(CONTROL_CELL_ID,
TO_CIRCUIT(circ),
1188 RELAY_COMMAND_RENDEZVOUS1,
1189 (
const char *) payload,
1193 log_warn(
LD_REND,
"Unable to send RENDEZVOUS1 cell on circuit %u "
1199 HS_METRICS_ERR_RDV_RENDEZVOUS1);
1208 log_warn(
LD_GENERAL,
"Failed to setup circ");
1215 memwipe(payload, 0,
sizeof(payload));
1226 const uint8_t *payload,
size_t payload_len)
1242 log_warn(
LD_REND,
"Unable to parse the INTRO_ESTABLISHED cell on "
1243 "circuit %u for service %s",
1286 if (BUG(!service->
state.ob_subcreds)) {
1306 const uint8_t *payload,
size_t payload_len)
1311 time_t now = time(NULL);
1333 HS_METRICS_ERR_INTRO_REQ_SUBCREDENTIAL);
1354 log_info(
LD_REND,
"We received an INTRODUCE2 cell with same REND_COOKIE "
1355 "field %ld seconds ago. Dropping cell.",
1356 (
long int) elapsed);
1358 HS_METRICS_ERR_INTRO_REQ_INTRODUCE2_REPLAY);
1370 "Adding introduction request to pqueue with effort: %u",
1393 memwipe(&data, 0,
sizeof(data));
1406 const uint8_t *ntor_key_seed,
size_t seed_len,
1407 int is_service_side)
1410 is_service_side))) {
1417 log_warn(
LD_REND,
"Couldn't get v3 %s cpath!",
1418 is_service_side ?
"service-side" :
"client-side");
1443 ssize_t payload_len;
1460 if (exit_node == NULL) {
1461 log_info(
LD_REND,
"Unable to get rendezvous point for circuit %u. "
1462 "Failing.",
TO_CIRCUIT(intro_circ)->n_circ_id);
1469 log_info(
LD_REND,
"Unable to setup INTRODUCE1 data. The chosen rendezvous "
1470 "point is unusable. Closing circuit.");
1496 if (BUG(payload_len < 0)) {
1500 if (relay_send_command_from_edge(CONTROL_CELL_ID,
TO_CIRCUIT(intro_circ),
1501 RELAY_COMMAND_INTRODUCE1,
1502 (
const char *) payload, payload_len,
1505 log_warn(
LD_REND,
"Unable to send INTRODUCE1 cell on circuit %u.",
1515 circuit_mark_for_close(
TO_CIRCUIT(rend_circ), END_CIRC_REASON_INTERNAL);
1518 memwipe(payload, 0,
sizeof(payload));
1527 ssize_t cell_len = 0;
1533 log_info(
LD_REND,
"Send an ESTABLISH_RENDEZVOUS cell on circuit %u",
1538 TO_CIRCUIT(circ)->timestamp_dirty = time(NULL);
1552 if (BUG(cell_len < 0)) {
1556 if (relay_send_command_from_edge(CONTROL_CELL_ID,
TO_CIRCUIT(circ),
1557 RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
1558 (
const char *) cell, cell_len,
1561 log_warn(
LD_REND,
"Unable to send ESTABLISH_RENDEZVOUS cell on "
const char * hex_str(const char *from, size_t fromlen)
void pathbias_count_use_attempt(origin_circuit_t *circ)
void pathbias_mark_use_success(origin_circuit_t *circ)
void circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
const node_t * build_state_get_exit_node(cpath_build_state_t *state)
Header file for circuitbuild.c.
origin_circuit_t * circuit_get_next_by_purpose(origin_circuit_t *start, uint8_t purpose)
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
int32_t circuit_initial_package_window(void)
Header file for circuitlist.c.
#define CIRCUIT_PURPOSE_S_CONNECT_REND
#define CIRCUIT_STATE_OPEN
#define CIRCUIT_PURPOSE_C_REND_JOINED
#define CIRCUIT_PURPOSE_S_INTRO
#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED
#define CIRCUIT_PURPOSE_S_REND_JOINED
#define CIRCUIT_PURPOSE_C_REND_READY
#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
#define CIRCUIT_PURPOSE_C_ESTABLISH_REND
#define CIRCUIT_PURPOSE_C_GENERAL
#define CIRCUIT_PURPOSE_HS_VANGUARDS
bool circuit_is_hs_v3(const circuit_t *circ)
bool circuit_purpose_is_hs_service(const uint8_t purpose)
void circuit_change_purpose(circuit_t *circ, uint8_t new_purpose)
int circuit_should_use_vanguards(uint8_t purpose)
void circuit_has_opened(origin_circuit_t *circ)
bool circuit_purpose_is_hs_client(const uint8_t purpose)
origin_circuit_t * circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, int flags)
void circuit_try_attaching_streams(origin_circuit_t *circ)
Header file for circuituse.c.
#define CIRCLAUNCH_NEED_CAPACITY
#define CIRCLAUNCH_ONEHOP_TUNNEL
#define CIRCLAUNCH_IS_INTERNAL
#define CIRCLAUNCH_NEED_UPTIME
mainloop_event_t * mainloop_event_postloop_new(void(*cb)(mainloop_event_t *, void *), void *userdata)
int mainloop_event_schedule(mainloop_event_t *event, const struct timeval *tv)
void mainloop_event_activate(mainloop_event_t *event)
Functions and types for monotonic times.
const or_options_t * get_options(void)
Header file for config.c.
congestion_control_t * congestion_control_new(const circuit_params_t *params, cc_path_t path)
Public APIs for congestion control.
static uint8_t congestion_control_sendme_inc(void)
Structure definitions for congestion control.
Circuit-build-stse structure.
int cpath_init_circuit_crypto(crypt_path_t *cpath, const char *key_data, size_t key_data_len, int reverse, int is_hs_v3)
void cpath_extend_linked_list(crypt_path_t **head_ptr, crypt_path_t *new_hop)
Header file for crypt_path.c.
Path structures for origin circuits.
int curve25519_keypair_generate(curve25519_keypair_t *keypair_out, int extra_strong)
int curve25519_public_key_is_ok(const curve25519_public_key_t *key)
void ed25519_pubkey_copy(ed25519_public_key_t *dest, const ed25519_public_key_t *src)
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2)
void crypto_rand(char *to, size_t n)
Common functions for using (pseudo-)random number generators.
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
const char * extend_info_describe(const extend_info_t *ei)
Header file for describe.c.
Header for core/or/extendinfo.c.
ssize_t hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie, uint8_t *cell_out)
ssize_t hs_cell_parse_introduce2(hs_cell_introduce2_data_t *data, const origin_circuit_t *circ, const hs_service_t *service, const hs_service_intro_point_t *ip)
ssize_t hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
ssize_t hs_cell_build_establish_intro(const char *circ_nonce, const hs_service_config_t *service_config, const hs_service_intro_point_t *ip, uint8_t *cell_out)
void hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data)
ssize_t hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie, size_t rendezvous_cookie_len, const uint8_t *rendezvous_handshake_info, size_t rendezvous_handshake_info_len, uint8_t *cell_out)
ssize_t hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, uint8_t *cell_out)
Header file containing cell data for the whole HS subsystem.
int top_of_rend_pqueue_is_worthwhile(hs_pow_service_state_t *pow_state)
static int queued_rend_request_is_too_old(pending_rend_t *req, time_t now)
void hs_circ_service_rp_has_opened(const hs_service_t *service, origin_circuit_t *circ)
static int get_subcredential_for_handling_intro2_cell(const hs_service_t *service, hs_cell_introduce2_data_t *data, const hs_subcredential_t *desc_subcred)
origin_circuit_t * hs_circ_service_get_intro_circ(const hs_service_intro_point_t *ip)
void hs_circ_cleanup_on_repurpose(circuit_t *circ)
static void cleanup_on_close_client_circ(circuit_t *circ)
static void register_intro_circ(const hs_service_intro_point_t *ip, origin_circuit_t *circ)
int hs_circ_send_introduce1(origin_circuit_t *intro_circ, origin_circuit_t *rend_circ, const hs_desc_intro_point_t *ip, const hs_subcredential_t *subcredential, const hs_pow_solution_t *pow_solution)
int hs_circ_launch_intro_point(hs_service_t *service, const hs_service_intro_point_t *ip, extend_info_t *ei, bool direct_conn)
static void finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop, int is_service_side)
void hs_circ_setup_congestion_control(origin_circuit_t *origin_circ, uint8_t sendme_inc, bool is_single_onion)
static int count_service_rp_circuits_pending(hs_service_t *service)
origin_circuit_t * hs_circ_service_get_established_intro_circ(const hs_service_intro_point_t *ip)
static hs_ident_circuit_t * create_intro_circuit_identifier(const hs_service_t *service, const hs_service_intro_point_t *ip)
static void retry_service_rendezvous_point(const origin_circuit_t *circ)
static void free_pending_rend(pending_rend_t *req)
#define MAX_CHEAP_REND_CIRCUITS_IN_PROGRESS
void rend_pqueue_clear(hs_pow_service_state_t *pow_state)
static void trim_rend_pqueue(hs_pow_service_state_t *pow_state, time_t now)
int hs_circ_service_intro_has_opened(hs_service_t *service, hs_service_intro_point_t *ip, const hs_service_descriptor_t *desc, origin_circuit_t *circ)
STATIC void launch_rendezvous_point_circuit(const hs_service_t *service, const ed25519_public_key_t *ip_auth_pubkey, const curve25519_keypair_t *ip_enc_key_kp, const hs_cell_intro_rdv_data_t *rdv_data, time_t now)
static void cleanup_on_free_client_circ(circuit_t *circ)
void hs_circ_cleanup_on_close(circuit_t *circ)
static int compare_rend_request_by_effort_(const void *_a, const void *_b)
static void send_establish_intro(const hs_service_t *service, hs_service_intro_point_t *ip, origin_circuit_t *circ)
int hs_circ_handle_introduce2(const hs_service_t *service, const origin_circuit_t *circ, hs_service_intro_point_t *ip, const hs_subcredential_t *subcredential, const uint8_t *payload, size_t payload_len)
int hs_circ_handle_intro_established(const hs_service_t *service, const hs_service_intro_point_t *ip, origin_circuit_t *circ, const uint8_t *payload, size_t payload_len)
static int can_relaunch_service_rendezvous_point(const origin_circuit_t *circ)
static unsigned int count_opened_desc_intro_point_circuits(const hs_service_t *service, const hs_service_descriptor_t *desc)
bool hs_circ_is_rend_sent_in_intro1(const origin_circuit_t *circ)
void hs_circ_retry_service_rendezvous_point(const origin_circuit_t *circ)
STATIC hs_ident_circuit_t * create_rp_circuit_identifier(const hs_service_t *service, const uint8_t *rendezvous_cookie, const curve25519_public_key_t *server_pk, const hs_ntor_rend_cell_keys_t *keys)
static int circuit_purpose_is_correct_for_rend(unsigned int circ_purpose, int is_service_side)
static int setup_introduce1_data(const hs_desc_intro_point_t *ip, const node_t *rp_node, const hs_subcredential_t *subcredential, hs_cell_introduce1_data_t *intro1_data)
int hs_circ_send_establish_rendezvous(origin_circuit_t *circ)
int hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ, const uint8_t *ntor_key_seed, size_t seed_len, int is_service_side)
void hs_circ_cleanup_on_free(circuit_t *circ)
static int enqueue_rend_request(const hs_service_t *service, hs_service_intro_point_t *ip, hs_cell_introduce2_data_t *data, time_t now)
static crypt_path_t * create_rend_cpath(const uint8_t *ntor_key_seed, size_t seed_len, int is_service_side)
static const char * get_service_anonymity_string(const hs_service_t *service)
Header file containing circuit data for the whole HS subsystem.
void hs_circuitmap_remove_circuit(circuit_t *circ)
void hs_circuitmap_register_intro_circ_v3_service_side(origin_circuit_t *circ, const ed25519_public_key_t *auth_key)
origin_circuit_t * hs_circuitmap_get_intro_circ_v3_service_side(const ed25519_public_key_t *auth_key)
Header file for hs_circuitmap.c.
void hs_client_circuit_cleanup_on_close(const circuit_t *circ)
void hs_client_circuit_cleanup_on_free(const circuit_t *circ)
Header file containing client data for the HS subsystem.
int hs_get_service_max_rend_failures(void)
extend_info_t * hs_get_extend_info_from_lspecs(const smartlist_t *lspecs, const curve25519_public_key_t *onion_key, int direct_conn)
int hs_service_requires_uptime_circ(const smartlist_t *ports)
Header file containing common data for the whole HS subsystem.
#define HS_LEGACY_RENDEZVOUS_CELL_SIZE
#define MAX_REND_FAILURES
hs_ident_circuit_t * hs_ident_circuit_new(const ed25519_public_key_t *identity_pk)
hs_ident_circuit_t * hs_ident_circuit_dup(const hs_ident_circuit_t *src)
Header file containing circuit and connection identifier data for the whole HS subsystem.
#define HS_REND_COOKIE_LEN
Header for feature/hs/hs_metrics.c.
#define hs_metrics_new_rdv(i)
#define hs_metrics_pow_pqueue_rdv(s, n)
#define hs_metrics_failed_rdv(i, reason)
#define hs_metrics_reject_intro_req(s, reason)
int hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed, size_t seed_len, uint8_t *keys_out, size_t keys_out_len)
bool hs_ob_service_is_instance(const hs_service_t *service)
Header file for the specific code for onion balance.
void hs_service_circuit_cleanup_on_close(const circuit_t *circ)
Header file containing service data for the HS subsystem.
#define log_fn(severity, domain, args,...)
Node information structure.
const curve25519_public_key_t * node_get_curve25519_onion_key(const node_t *node)
Header file for nodelist.c.
Header file for onion_crypto.c.
Master header file for Tor-specific functionality.
#define RELAY_PAYLOAD_SIZE
Origin circuit structure.
Header file for policies.c.
Header file for rephist.c.
int replaycache_add_test_and_elapsed(replaycache_t *r, const void *data, size_t len, time_t *elapsed)
void * smartlist_pqueue_pop(smartlist_t *sl, int(*compare)(const void *a, const void *b), ptrdiff_t idx_field_offset)
void smartlist_pqueue_add(smartlist_t *sl, int(*compare)(const void *a, const void *b), ptrdiff_t idx_field_offset, void *item)
void * smartlist_pop_last(smartlist_t *sl)
smartlist_t * smartlist_new(void)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
struct hs_token_t * hs_token
uint16_t marked_for_close
struct congestion_control_t * ccontrol
extend_info_t * chosen_exit
unsigned int need_capacity
struct crypt_path_t * prev
char rend_circ_nonce[DIGEST_LEN]
struct congestion_control_t * ccontrol
curve25519_public_key_t onion_pk
uint8_t rendezvous_cookie[REND_COOKIE_LEN]
curve25519_public_key_t client_pk
smartlist_t * link_specifiers
const ed25519_public_key_t * auth_pk
const struct hs_subcredential_t * subcredential
const hs_pow_solution_t * pow_solution
const curve25519_keypair_t * client_kp
const curve25519_public_key_t * enc_pk
const uint8_t * rendezvous_cookie
const curve25519_public_key_t * onion_pk
smartlist_t * link_specifiers
const ed25519_public_key_t * auth_pk
const curve25519_keypair_t * enc_kp
replaycache_t * replay_cache
const struct hs_subcredential_t * subcredentials
hs_cell_intro_rdv_data_t rdv_data
curve25519_public_key_t enc_key
tor_cert_t * auth_key_cert
uint8_t rendezvous_cookie[HS_REND_COOKIE_LEN]
ed25519_public_key_t intro_auth_pk
curve25519_keypair_t rendezvous_client_kp
curve25519_public_key_t intro_enc_pk
uint8_t rendezvous_ntor_key_seed[DIGEST256_LEN]
ed25519_public_key_t identity_pk
uint8_t rendezvous_handshake_info[CURVE25519_PUBKEY_LEN+DIGEST256_LEN]
unsigned int is_single_onion
unsigned int num_intro_points
unsigned int has_pow_defenses_enabled
hs_service_intropoints_t intro_points
ed25519_keypair_t auth_key_kp
replaycache_t * replay_cache
curve25519_keypair_t enc_key_kp
uint64_t introduce2_count
ed25519_public_key_t identity_pk
replaycache_t * replay_cache_rend_cookie
hs_pow_service_state_t * pow_state
unsigned int num_intro_circ_launched
char onion_address[HS_SERVICE_ADDR_LEN_BASE32+1]
hs_service_config_t config
struct hs_ident_circuit_t * hs_ident
cpath_build_state_t * build_state
unsigned int hs_with_pow_circ
ed25519_public_key_t signed_key
#define MOCK_IMPL(rv, funcname, arglist)
void token_bucket_ctr_refill(token_bucket_ctr_t *bucket, uint32_t now_ts_sec)
#define tor_assert_nonfatal_unreached()
#define CURVE25519_PUBKEY_LEN