Commit c2d5ec5e authored by Nick Mathewson's avatar Nick Mathewson 🏃
Browse files

Merge branch 'maint-0.4.2' into bug40076_042

parents c4742b89 cdb0e6c2
......@@ -20,4 +20,4 @@ int router_append_dirobj_signature(char *buf, size_t buf_len,
const char *digest,
size_t digest_len,
crypto_pk_t *private_key);
#endif
#endif /* !defined(TOR_SIGNING_H) */
......@@ -26,7 +26,7 @@ void dump_desc_init(void);
log_debug(LD_MM, "Area for %s has %lu allocated; using %lu.", \
name, (unsigned long)alloc, (unsigned long)used); \
STMT_END
#else /* !(defined(DEBUG_AREA_ALLOC)) */
#else /* !defined(DEBUG_AREA_ALLOC) */
#define DUMP_AREA(a,name) STMT_NIL
#endif /* defined(DEBUG_AREA_ALLOC) */
......@@ -51,6 +51,6 @@ EXTERN(struct smartlist_t *, descs_dumped)
MOCK_DECL(STATIC dumped_desc_t *, dump_desc_populate_one_file,
(const char *dirname, const char *f));
STATIC void dump_desc_populate_fifo_from_directory(const char *dirname);
#endif
#endif /* defined(UNPARSEABLE_PRIVATE) */
#endif /* !defined(TOR_UNPARSEABLE_H) */
......@@ -35,8 +35,9 @@ hibernating, phase 2:
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
#include "core/or/connection_or.h"
#include "feature/control/control.h"
#include "feature/control/control_events.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/defs/time.h"
#include "feature/hibernate/hibernate.h"
#include "core/mainloop/mainloop.h"
#include "feature/relay/router.h"
......@@ -56,7 +57,7 @@ hibernating, phase 2:
* Coverity. Here's a kludge to unconfuse it.
*/
# define __INCLUDE_LEVEL__ 2
# endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */
#endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */
#include <systemd/sd-daemon.h>
#endif /* defined(HAVE_SYSTEMD) */
......@@ -66,8 +67,9 @@ static hibernate_state_t hibernate_state = HIBERNATE_STATE_INITIAL;
/** If are hibernating, when do we plan to wake up? Set to 0 if we
* aren't hibernating. */
static time_t hibernate_end_time = 0;
/** If we are shutting down, when do we plan finally exit? Set to 0 if
* we aren't shutting down. */
/** If we are shutting down, when do we plan to finally exit? Set to 0 if we
* aren't shutting down. (This is obsolete; scheduled shutdowns are supposed
* to happen from mainloop_schedule_shutdown() now.) */
static time_t shutdown_time = 0;
/** A timed event that we'll use when it's time to wake up from
......@@ -560,7 +562,7 @@ time_to_record_bandwidth_usage(time_t now)
/* Note every 600 sec */
#define NOTE_INTERVAL (600)
/* Or every 20 megabytes */
#define NOTE_BYTES 20*(1024*1024)
#define NOTE_BYTES (20*1024*1024)
static uint64_t last_read_bytes_noted = 0;
static uint64_t last_written_bytes_noted = 0;
static time_t last_time_noted = 0;
......@@ -813,7 +815,7 @@ hibernate_soft_limit_reached(void)
* We want to stop accepting connections when ALL of the following are true:
* - We expect to use up the remaining bytes in under 3 hours
* - We have used up 95% of our bytes.
* - We have less than 500MB of bytes left.
* - We have less than 500MBytes left.
*/
uint64_t soft_limit = (uint64_t) (acct_max * SOFT_LIM_PCT);
if (acct_max > SOFT_LIM_BYTES && acct_max - SOFT_LIM_BYTES > soft_limit) {
......@@ -831,8 +833,6 @@ hibernate_soft_limit_reached(void)
return get_accounting_bytes() >= soft_limit;
}
#define TOR_USEC_PER_SEC (1000000)
/** Called when we get a SIGINT, or when bandwidth soft limit is
* reached. Puts us into "loose hibernation": we don't accept new
* connections, but we continue handling old ones. */
......@@ -867,7 +867,13 @@ hibernate_begin(hibernate_state_t new_state, time_t now)
log_notice(LD_GENERAL,"Interrupt: we have stopped accepting new "
"connections, and will shut down in %d seconds. Interrupt "
"again to exit now.", options->ShutdownWaitLength);
shutdown_time = time(NULL) + options->ShutdownWaitLength;
/* We add an arbitrary delay here so that even if something goes wrong
* with the mainloop shutdown code, we can still shutdown from
* consider_hibernation() if we call it... but so that the
* mainloop_schedule_shutdown() mechanism will be the first one called.
*/
shutdown_time = time(NULL) + options->ShutdownWaitLength + 5;
mainloop_schedule_shutdown(options->ShutdownWaitLength);
#ifdef HAVE_SYSTEMD
/* tell systemd that we may need more than the default 90 seconds to shut
* down so they don't kill us. add some extra time to actually finish
......@@ -887,7 +893,7 @@ hibernate_begin(hibernate_state_t new_state, time_t now)
*/
sd_notifyf(0, "EXTEND_TIMEOUT_USEC=%" PRIu64,
((uint64_t)(options->ShutdownWaitLength) + 30) * TOR_USEC_PER_SEC);
#endif
#endif /* defined(HAVE_SYSTEMD) */
} else { /* soft limit reached */
hibernate_end_time = interval_end_time;
}
......@@ -1096,11 +1102,12 @@ consider_hibernation(time_t now)
hibernate_state_t prev_state = hibernate_state;
/* If we're in 'exiting' mode, then we just shut down after the interval
* elapses. */
* elapses. The mainloop was supposed to catch this via
* mainloop_schedule_shutdown(), but apparently it didn't. */
if (hibernate_state == HIBERNATE_STATE_EXITING) {
tor_assert(shutdown_time);
if (shutdown_time <= now) {
log_notice(LD_GENERAL, "Clean shutdown finished. Exiting.");
log_notice(LD_BUG, "Mainloop did not catch shutdown event; exiting.");
tor_shutdown_event_loop_and_exit(0);
}
return; /* if exiting soon, don't worry about bandwidth limits */
......@@ -1112,7 +1119,7 @@ consider_hibernation(time_t now)
if (hibernate_end_time > now && accounting_enabled) {
/* If we're hibernating, don't wake up until it's time, regardless of
* whether we're in a new interval. */
return ;
return;
} else {
hibernate_end_time_elapsed(now);
}
......@@ -1240,8 +1247,6 @@ on_hibernate_state_change(hibernate_state_t prev_state)
if (prev_state != HIBERNATE_STATE_INITIAL) {
rescan_periodic_events(get_options());
}
reschedule_per_second_timer();
}
/** Free all resources held by the accounting module */
......
......@@ -32,6 +32,7 @@ int getinfo_helper_accounting(control_connection_t *conn,
const char **errmsg);
uint64_t get_accounting_max_total(void);
void accounting_free_all(void);
bool accounting_tor_is_dormant(void);
#ifdef HIBERNATE_PRIVATE
/** Possible values of hibernate_state */
......
......@@ -710,6 +710,11 @@ cache_clean_v3_as_client(time_t now)
MAP_DEL_CURRENT(key);
entry_size = cache_get_client_entry_size(entry);
bytes_removed += entry_size;
/* We just removed an old descriptor. We need to close all intro circuits
* so we don't have leftovers that can be selected while lacking a
* descriptor. We leave the rendezvous circuits opened because they could
* be in use. */
hs_client_close_intro_circuits_from_desc(entry->desc);
/* Entry is not in the cache anymore, destroy it. */
cache_client_desc_free(entry);
/* Update our OOM. We didn't use the remove() function because we are in
......
......@@ -473,10 +473,132 @@ introduce1_set_legacy_id(trn_cell_introduce1_t *cell,
}
}
/* Build and add to the given DoS cell extension the given parameter type and
* value. */
static void
build_establish_intro_dos_param(trn_cell_extension_dos_t *dos_ext,
uint8_t param_type, uint64_t param_value)
{
trn_cell_extension_dos_param_t *dos_param =
trn_cell_extension_dos_param_new();
/* Extra safety. We should never send an unknown parameter type. */
tor_assert(param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC ||
param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC);
trn_cell_extension_dos_param_set_type(dos_param, param_type);
trn_cell_extension_dos_param_set_value(dos_param, param_value);
trn_cell_extension_dos_add_params(dos_ext, dos_param);
/* Not freeing the trunnel object because it is now owned by dos_ext. */
}
/* Build the DoS defense cell extension and put it in the given extensions
* object. Return 0 on success, -1 on failure. (Right now, failure is only
* possible if there is a bug.) */
static int
build_establish_intro_dos_extension(const hs_service_config_t *service_config,
trn_cell_extension_t *extensions)
{
ssize_t ret;
size_t dos_ext_encoded_len;
uint8_t *field_array;
trn_cell_extension_field_t *field = NULL;
trn_cell_extension_dos_t *dos_ext = NULL;
tor_assert(service_config);
tor_assert(extensions);
/* We are creating a cell extension field of the type DoS. */
field = trn_cell_extension_field_new();
trn_cell_extension_field_set_field_type(field,
TRUNNEL_CELL_EXTENSION_TYPE_DOS);
/* Build DoS extension field. We will put in two parameters. */
dos_ext = trn_cell_extension_dos_new();
trn_cell_extension_dos_set_n_params(dos_ext, 2);
/* Build DoS parameter INTRO2 rate per second. */
build_establish_intro_dos_param(dos_ext,
TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC,
service_config->intro_dos_rate_per_sec);
/* Build DoS parameter INTRO2 burst per second. */
build_establish_intro_dos_param(dos_ext,
TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC,
service_config->intro_dos_burst_per_sec);
/* Set the field with the encoded DoS extension. */
ret = trn_cell_extension_dos_encoded_len(dos_ext);
if (BUG(ret <= 0)) {
goto err;
}
dos_ext_encoded_len = ret;
/* Set length field and the field array size length. */
trn_cell_extension_field_set_field_len(field, dos_ext_encoded_len);
trn_cell_extension_field_setlen_field(field, dos_ext_encoded_len);
/* Encode the DoS extension into the cell extension field. */
field_array = trn_cell_extension_field_getarray_field(field);
ret = trn_cell_extension_dos_encode(field_array,
trn_cell_extension_field_getlen_field(field), dos_ext);
if (BUG(ret <= 0)) {
goto err;
}
tor_assert(ret == (ssize_t) dos_ext_encoded_len);
/* Finally, encode field into the cell extension. */
trn_cell_extension_add_fields(extensions, field);
/* We've just add an extension field to the cell extensions so increment the
* total number. */
trn_cell_extension_set_num(extensions,
trn_cell_extension_get_num(extensions) + 1);
/* Cleanup. DoS extension has been encoded at this point. */
trn_cell_extension_dos_free(dos_ext);
return 0;
err:
trn_cell_extension_field_free(field);
trn_cell_extension_dos_free(dos_ext);
return -1;
}
/* ========== */
/* Public API */
/* ========== */
/* Allocate and build all the ESTABLISH_INTRO cell extension. The given
* extensions pointer is always set to a valid cell extension object. */
STATIC trn_cell_extension_t *
build_establish_intro_extensions(const hs_service_config_t *service_config,
const hs_service_intro_point_t *ip)
{
int ret;
trn_cell_extension_t *extensions;
tor_assert(service_config);
tor_assert(ip);
extensions = trn_cell_extension_new();
trn_cell_extension_set_num(extensions, 0);
/* If the defense has been enabled service side (by the operator with a
* torrc option) and the intro point does support it. */
if (service_config->has_dos_defense_enabled &&
ip->support_intro2_dos_defense) {
/* This function takes care to increment the number of extensions. */
ret = build_establish_intro_dos_extension(service_config, extensions);
if (ret < 0) {
/* Return no extensions on error. */
goto end;
}
}
end:
return extensions;
}
/* Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point
* object. The encoded cell is put in cell_out that MUST at least be of the
* size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on success else
......@@ -484,15 +606,17 @@ introduce1_set_legacy_id(trn_cell_introduce1_t *cell,
* legacy cell creation. */
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)
{
ssize_t cell_len = -1;
uint16_t sig_len = ED25519_SIG_LEN;
trn_cell_extension_t *ext;
trn_cell_establish_intro_t *cell = NULL;
trn_cell_extension_t *extensions;
tor_assert(circ_nonce);
tor_assert(service_config);
tor_assert(ip);
/* Quickly handle the legacy IP. */
......@@ -505,11 +629,12 @@ hs_cell_build_establish_intro(const char *circ_nonce,
goto done;
}
/* Build the extensions, if any. */
extensions = build_establish_intro_extensions(service_config, ip);
/* Set extension data. None used here. */
ext = trn_cell_extension_new();
trn_cell_extension_set_num(ext, 0);
cell = trn_cell_establish_intro_new();
trn_cell_establish_intro_set_extensions(cell, ext);
trn_cell_establish_intro_set_extensions(cell, extensions);
/* Set signature size. Array is then allocated in the cell. We need to do
* this early so we can use trunnel API to get the signature length. */
trn_cell_establish_intro_set_sig_len(cell, sig_len);
......@@ -758,7 +883,14 @@ hs_cell_parse_introduce2(hs_cell_introduce2_data_t *data,
idx < trn_cell_introduce_encrypted_get_nspec(enc_cell); idx++) {
link_specifier_t *lspec =
trn_cell_introduce_encrypted_get_nspecs(enc_cell, idx);
smartlist_add(data->link_specifiers, hs_link_specifier_dup(lspec));
if (BUG(!lspec)) {
goto done;
}
link_specifier_t *lspec_dup = link_specifier_dup(lspec);
if (BUG(!lspec_dup)) {
goto done;
}
smartlist_add(data->link_specifiers, lspec_dup);
}
/* Success. */
......@@ -949,4 +1081,3 @@ hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data)
/* The data object has no ownership of any members. */
memwipe(data, 0, sizeof(hs_cell_introduce1_data_t));
}
......@@ -79,6 +79,7 @@ typedef struct hs_cell_introduce2_data_t {
/* Build cell API. */
ssize_t hs_cell_build_establish_intro(const char *circ_nonce,
const hs_service_config_t *config,
const hs_service_intro_point_t *ip,
uint8_t *cell_out);
ssize_t hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie,
......@@ -105,5 +106,15 @@ int hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len,
/* Util API. */
void hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data);
#ifdef TOR_UNIT_TESTS
#include "trunnel/hs/cell_common.h"
STATIC trn_cell_extension_t *
build_establish_intro_extensions(const hs_service_config_t *service_config,
const hs_service_intro_point_t *ip);
#endif /* defined(TOR_UNIT_TESTS) */
#endif /* !defined(TOR_HS_CELL_H) */
......@@ -15,6 +15,7 @@
#include "core/or/circuituse.h"
#include "core/or/policies.h"
#include "core/or/relay.h"
#include "core/or/crypt_path.h"
#include "feature/client/circpathbias.h"
#include "feature/hs/hs_cell.h"
#include "feature/hs/hs_circuit.h"
......@@ -89,7 +90,7 @@ create_rend_cpath(const uint8_t *ntor_key_seed, size_t seed_len,
cpath = tor_malloc_zero(sizeof(crypt_path_t));
cpath->magic = CRYPT_PATH_MAGIC;
if (circuit_init_cpath_crypto(cpath, (char*)keys, sizeof(keys),
if (cpath_init_circuit_crypto(cpath, (char*)keys, sizeof(keys),
is_service_side, 1) < 0) {
tor_free(cpath);
goto err;
......@@ -126,7 +127,7 @@ create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body)
goto err;
}
/* ... and set up cpath. */
if (circuit_init_cpath_crypto(hop,
if (cpath_init_circuit_crypto(hop,
keys+DIGEST_LEN, sizeof(keys)-DIGEST_LEN,
0, 0) < 0)
goto err;
......@@ -177,7 +178,7 @@ finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop,
circ->hs_circ_has_timed_out = 0;
/* Append the hop to the cpath of this circuit */
onion_append_to_cpath(&circ->cpath, hop);
cpath_extend_linked_list(&circ->cpath, hop);
/* In legacy code, 'pending_final_cpath' points to the final hop we just
* appended to the cpath. We set the original pointer to NULL so that we
......@@ -258,8 +259,7 @@ create_rp_circuit_identifier(const hs_service_t *service,
tor_assert(server_pk);
tor_assert(keys);
ident = hs_ident_circuit_new(&service->keys.identity_pk,
HS_IDENT_CIRCUIT_RENDEZVOUS);
ident = hs_ident_circuit_new(&service->keys.identity_pk);
/* Copy the RENDEZVOUS_COOKIE which is the unique identifier. */
memcpy(ident->rendezvous_cookie, rendezvous_cookie,
sizeof(ident->rendezvous_cookie));
......@@ -293,8 +293,7 @@ create_intro_circuit_identifier(const hs_service_t *service,
tor_assert(service);
tor_assert(ip);
ident = hs_ident_circuit_new(&service->keys.identity_pk,
HS_IDENT_CIRCUIT_INTRO);
ident = hs_ident_circuit_new(&service->keys.identity_pk);
ed25519_pubkey_copy(&ident->intro_auth_pk, &ip->auth_key_kp.pubkey);
return ident;
......@@ -318,7 +317,7 @@ send_establish_intro(const hs_service_t *service,
/* Encode establish intro cell. */
cell_len = hs_cell_build_establish_intro(circ->cpath->prev->rend_circ_nonce,
ip, payload);
&service->config, ip, payload);
if (cell_len < 0) {
log_warn(LD_REND, "Unable to encode ESTABLISH_INTRO cell for service %s "
"on circuit %u. Closing circuit.",
......@@ -388,10 +387,7 @@ launch_rendezvous_point_circuit(const hs_service_t *service,
&data->onion_pk,
service->config.is_single_onion);
if (info == NULL) {
/* We are done here, we can't extend to the rendezvous point.
* If you're running an IPv6-only v3 single onion service on 0.3.2 or with
* 0.3.2 clients, and somehow disable the option check, it will fail here.
*/
/* We are done here, we can't extend to the rendezvous point. */
log_fn(LOG_PROTOCOL_WARN, LD_REND,
"Not enough info to open a circuit to a rendezvous point for "
"%s service %s.",
......@@ -569,81 +565,6 @@ retry_service_rendezvous_point(const origin_circuit_t *circ)
return;
}
/* Add all possible link specifiers in node to lspecs:
* - legacy ID is mandatory thus MUST be present in node;
* - include ed25519 link specifier if present in the node, and the node
* supports ed25519 link authentication, even if its link versions are not
* compatible with us;
* - include IPv4 link specifier, if the primary address is not IPv4, log a
* BUG() warning, and return an empty smartlist;
* - include IPv6 link specifier if present in the node. */
static void
get_lspecs_from_node(const node_t *node, smartlist_t *lspecs)
{
link_specifier_t *ls;
tor_addr_port_t ap;
tor_assert(node);
tor_assert(lspecs);
/* Get the relay's IPv4 address. */
node_get_prim_orport(node, &ap);
/* We expect the node's primary address to be a valid IPv4 address.
* This conforms to the protocol, which requires either an IPv4 or IPv6
* address (or both). */
if (BUG(!tor_addr_is_v4(&ap.addr)) ||
BUG(!tor_addr_port_is_valid_ap(&ap, 0))) {
return;
}
ls = link_specifier_new();
link_specifier_set_ls_type(ls, LS_IPV4);
link_specifier_set_un_ipv4_addr(ls, tor_addr_to_ipv4h(&ap.addr));
link_specifier_set_un_ipv4_port(ls, ap.port);
/* Four bytes IPv4 and two bytes port. */
link_specifier_set_ls_len(ls, sizeof(ap.addr.addr.in_addr) +
sizeof(ap.port));
smartlist_add(lspecs, ls);
/* Legacy ID is mandatory and will always be present in node. */
ls = link_specifier_new();
link_specifier_set_ls_type(ls, LS_LEGACY_ID);
memcpy(link_specifier_getarray_un_legacy_id(ls), node->identity,
link_specifier_getlen_un_legacy_id(ls));
link_specifier_set_ls_len(ls, link_specifier_getlen_un_legacy_id(ls));
smartlist_add(lspecs, ls);
/* ed25519 ID is only included if the node has it, and the node declares a
protocol version that supports ed25519 link authentication, even if that
link version is not compatible with us. (We are sending the ed25519 key
to another tor, which may support different link versions.) */
if (!ed25519_public_key_is_zero(&node->ed25519_id) &&
node_supports_ed25519_link_authentication(node, 0)) {
ls = link_specifier_new();
link_specifier_set_ls_type(ls, LS_ED25519_ID);
memcpy(link_specifier_getarray_un_ed25519_id(ls), &node->ed25519_id,
link_specifier_getlen_un_ed25519_id(ls));
link_specifier_set_ls_len(ls, link_specifier_getlen_un_ed25519_id(ls));
smartlist_add(lspecs, ls);
}
/* Check for IPv6. If so, include it as well. */
if (node_has_ipv6_orport(node)) {
ls = link_specifier_new();
node_get_pref_ipv6_orport(node, &ap);
link_specifier_set_ls_type(ls, LS_IPV6);
size_t addr_len = link_specifier_getlen_un_ipv6_addr(ls);
const uint8_t *in6_addr = tor_addr_to_in6_addr8(&ap.addr);
uint8_t *ipv6_array = link_specifier_getarray_un_ipv6_addr(ls);
memcpy(ipv6_array, in6_addr, addr_len);
link_specifier_set_un_ipv6_port(ls, ap.port);
/* Sixteen bytes IPv6 and two bytes port. */
link_specifier_set_ls_len(ls, addr_len + sizeof(ap.port));
smartlist_add(lspecs, ls);
}
}
/* Using the given descriptor intro point ip, the node of the
* rendezvous point rp_node and the service's subcredential, populate the
* already allocated intro1_data object with the needed key material and link
......@@ -666,10 +587,9 @@ setup_introduce1_data(const hs_desc_intro_point_t *ip,
tor_assert(subcredential);
tor_assert(intro1_data);
/* Build the link specifiers from the extend information of the rendezvous
* circuit that we've picked previously. */
rp_lspecs = smartlist_new();
get_lspecs_from_node(rp_node, rp_lspecs);
/* Build the link specifiers from the node at the end of the rendezvous
* circuit that we opened for this introduction. */
rp_lspecs = node_get_link_specifier_smartlist(rp_node, 0);
if (smartlist_len(rp_lspecs) == 0) {
/* We can't rendezvous without link specifiers. */
smartlist_free(rp_lspecs);
......@@ -1060,9 +980,7 @@ hs_circ_handle_introduce2(const hs_service_t *service,
ret = 0;
done:
SMARTLIST_FOREACH(data.link_specifiers, link_specifier_t *, lspec,
link_specifier_free(lspec));
smartlist_free(data.link_specifiers);
link_specifier_smartlist_free(data.link_specifiers);
memwipe(&data, 0, sizeof(data));
return ret;
}
......
......@@ -272,6 +272,33 @@ hs_circuitmap_get_or_circuit(hs_token_type_t type,
/**** Public relay-side getters: */
/* Public function: Return v2 and v3 introduction circuit to this relay.
* Always return a newly allocated list for which it is the caller's
* responsability to free it. */
smartlist_t *
hs_circuitmap_get_all_intro_circ_relay_side(void)
{
circuit_t **iter;
smartlist_t *circuit_list = smartlist_new();
HT_FOREACH(iter, hs_circuitmap_ht, the_hs_circuitmap) {
circuit_t *circ = *iter;
/* An origin circuit or purpose is wrong or the hs token is not set to be
* a v2 or v3 intro relay side type, we ignore the circuit. Else, we have
* a match so add it to our list. */
if (CIRCUIT_IS_ORIGIN(circ) ||
circ->purpose != CIRCUIT_PURPOSE_INTRO_POINT ||
(circ->hs_token->type != HS_TOKEN_INTRO_V3_RELAY_SIDE &&
circ->hs_token->type != HS_TOKEN_INTRO_V2_RELAY_SIDE)) {
continue;
}
smartlist_add(circuit_list, circ);
}
return circuit_list;
}
/* Public function: Return a v3 introduction circuit to this relay with
* <b>auth_key</b>. Return NULL if no such circuit is found in the
* circuitmap. */
......
......@@ -34,6 +34,8 @@ void hs_circuitmap_register_intro_circ_v2_relay_side(struct or_circuit_t *circ,
void hs_circuitmap_register_intro_circ_v3_relay_side(struct or_circuit_t *circ,
const ed25519_public_key_t *auth_key);
smartlist_t *hs_circuitmap_get_all_intro_circ_relay_side(void);
/** Public service-side API: */
struct origin_circuit_t *
......
......@@ -167,9 +167,7 @@ purge_hid_serv_request(const ed25519_public_key_t *identity_pk)
* some point and we don't care about those anymore. */
hs_build_blinded_pubkey(identity_pk, NULL, 0,
hs_get_time_period_num(0), &blinded_pk);
if (BUG(ed25519_public_to_base64(base64_blinded_pk, &blinded_pk) < 0)) {
return;
}
ed25519_public_to_base64(base64_blinded_pk, &blinded_pk);
/* Purge last hidden service request from cache for this blinded key. */
hs_purge_hid_serv_from_last_hid_serv_requests(base64_blinded_pk);
}
......@@ -356,7 +354,6 @@ directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
ed25519_public_key_t blinded_pubkey;
char base64_blinded_pubkey[ED25519_BASE64_LEN + 1];
hs_ident_dir_conn_t hs_conn_dir_ident;
int retval;
tor_assert(hsdir);
tor_assert(onion_identity_pk);
......@@ -365,10 +362,7 @@ directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
hs_build_blinded_pubkey(onion_identity_pk, NULL, 0,
current_time_period, &blinded_pubkey);
/* ...and base64 it. */
retval = ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
if (BUG(retval < 0)) {
return HS_CLIENT_FETCH_ERROR;
}
ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
/* Copy onion pk to a dir_ident so that we attach it to the dir conn */
hs_ident_dir_conn_init(onion_identity_pk, &blinded_pubkey,
......@@ -407,7 +401,6 @@ directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
STATIC routerstatus_t *
pick_hsdir_v3(const ed25519_public_key_t *onion_identity_pk)
{
int retval;