aboutsummaryrefslogtreecommitdiff
path: root/src/feature/hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/feature/hs')
-rw-r--r--src/feature/hs/hs_cache.c81
-rw-r--r--src/feature/hs/hs_cache.h20
-rw-r--r--src/feature/hs/hs_cell.c78
-rw-r--r--src/feature/hs/hs_circuit.c157
-rw-r--r--src/feature/hs/hs_client.c7
-rw-r--r--src/feature/hs/hs_common.c261
-rw-r--r--src/feature/hs/hs_common.h23
-rw-r--r--src/feature/hs/hs_config.c55
-rw-r--r--src/feature/hs/hs_descriptor.c1
-rw-r--r--src/feature/hs/hs_service.c97
-rw-r--r--src/feature/hs/hs_service.h5
11 files changed, 154 insertions, 631 deletions
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c
index 765323df0d..ac43e78767 100644
--- a/src/feature/hs/hs_cache.c
+++ b/src/feature/hs/hs_cache.c
@@ -19,13 +19,15 @@
#include "feature/hs/hs_descriptor.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/rend/rendcache.h"
#include "feature/stats/rephist.h"
#include "feature/hs/hs_cache.h"
#include "feature/nodelist/networkstatus_st.h"
+/* Total counter of the cache size. */
+static size_t hs_cache_total_allocation = 0;
+
static int cached_client_descriptor_has_expired(time_t now,
const hs_cache_client_descriptor_t *cached_desc);
@@ -164,7 +166,7 @@ cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc)
* remove the entry we currently have from our cache so we can then
* store the new one. */
remove_v3_desc_as_dir(cache_entry);
- rend_cache_decrement_allocation(cache_get_dir_entry_size(cache_entry));
+ hs_cache_decrement_allocation(cache_get_dir_entry_size(cache_entry));
cache_dir_desc_free(cache_entry);
}
/* Store the descriptor we just got. We are sure here that either we
@@ -174,7 +176,7 @@ cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc)
/* Update our total cache size with this entry for the OOM. This uses the
* old HS protocol cache subsystem for which we are tied with. */
- rend_cache_increment_allocation(cache_get_dir_entry_size(desc));
+ hs_cache_increment_allocation(cache_get_dir_entry_size(desc));
/* Update HSv3 statistics */
if (get_options()->HiddenServiceStatistics) {
@@ -259,7 +261,7 @@ cache_clean_v3_as_dir(time_t now, time_t global_cutoff)
/* Entry is not in the cache anymore, destroy it. */
cache_dir_desc_free(entry);
/* Update our cache entry allocation size for the OOM. */
- rend_cache_decrement_allocation(entry_size);
+ hs_cache_decrement_allocation(entry_size);
/* Logging. */
{
char key_b64[BASE64_DIGEST256_LEN + 1];
@@ -336,12 +338,6 @@ hs_cache_lookup_as_dir(uint32_t version, const char *query,
void
hs_cache_clean_as_dir(time_t now)
{
- time_t cutoff;
-
- /* Start with v2 cache cleaning. */
- cutoff = now - rend_cache_max_entry_lifetime();
- rend_cache_clean_v2_descs_as_dir(cutoff);
-
/* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function
* to compute the cutoff by itself using the lifetime value. */
cache_clean_v3_as_dir(now, 0);
@@ -387,7 +383,7 @@ remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc)
tor_assert(desc);
digest256map_remove(hs_cache_v3_client, desc->key.pubkey);
/* Update cache size with this entry for the OOM handler. */
- rend_cache_decrement_allocation(cache_get_client_entry_size(desc));
+ hs_cache_decrement_allocation(cache_get_client_entry_size(desc));
}
/** Store a given descriptor in our cache. */
@@ -397,7 +393,7 @@ store_v3_desc_as_client(hs_cache_client_descriptor_t *desc)
tor_assert(desc);
digest256map_set(hs_cache_v3_client, desc->key.pubkey, desc);
/* Update cache size with this entry for the OOM handler. */
- rend_cache_increment_allocation(cache_get_client_entry_size(desc));
+ hs_cache_increment_allocation(cache_get_client_entry_size(desc));
}
/** Query our cache and return the entry or NULL if not found or if expired. */
@@ -796,7 +792,7 @@ cache_clean_v3_as_client(time_t now)
cache_client_desc_free(entry);
/* Update our OOM. We didn't use the remove() function because we are in
* a loop so we have to explicitly decrement. */
- rend_cache_decrement_allocation(entry_size);
+ hs_cache_decrement_allocation(entry_size);
/* Logging. */
{
char key_b64[BASE64_DIGEST256_LEN + 1];
@@ -934,8 +930,6 @@ hs_cache_remove_as_client(const ed25519_public_key_t *key)
void
hs_cache_clean_as_client(time_t now)
{
- /* Start with v2 cache cleaning. */
- rend_cache_clean(now, REND_CACHE_TYPE_CLIENT);
/* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function
* to compute the cutoff by itself using the lifetime value. */
cache_clean_v3_as_client(now);
@@ -952,7 +946,7 @@ hs_cache_purge_as_client(void)
cache_client_desc_free(entry);
/* Update our OOM. We didn't use the remove() function because we are in
* a loop so we have to explicitly decrement. */
- rend_cache_decrement_allocation(entry_size);
+ hs_cache_decrement_allocation(entry_size);
} DIGEST256MAP_FOREACH_END;
log_info(LD_REND, "Hidden service client descriptor cache purged.");
@@ -1074,19 +1068,16 @@ hs_cache_handle_oom(time_t now, size_t min_remove_bytes)
/* The algorithm is as follow. K is the oldest expected descriptor age.
*
- * 1) Deallocate all entries from v2 cache that are older than K hours.
- * 1.1) If the amount of remove bytes has been reached, stop.
- * 2) Deallocate all entries from v3 cache that are older than K hours
+ * 1) Deallocate all entries from v3 cache that are older than K hours
* 2.1) If the amount of remove bytes has been reached, stop.
- * 3) Set K = K - RendPostPeriod and repeat process until K is < 0.
+ * 2) Set K = K - RendPostPeriod and repeat process until K is < 0.
*
* This ends up being O(Kn).
*/
/* Set K to the oldest expected age in seconds which is the maximum
- * lifetime of a cache entry. We'll use the v2 lifetime because it's much
- * bigger than the v3 thus leading to cleaning older descriptors. */
- k = rend_cache_max_entry_lifetime();
+ * lifetime of a cache entry. */
+ k = hs_cache_max_entry_lifetime();
do {
time_t cutoff;
@@ -1099,9 +1090,6 @@ hs_cache_handle_oom(time_t now, size_t min_remove_bytes)
/* Compute a cutoff value with K and the current time. */
cutoff = now - k;
- /* Start by cleaning the v2 cache with that cutoff. */
- bytes_removed += rend_cache_clean_v2_descs_as_dir(cutoff);
-
if (bytes_removed < min_remove_bytes) {
/* We haven't remove enough bytes so clean v3 cache. */
bytes_removed += cache_clean_v3_as_dir(now, cutoff);
@@ -1150,4 +1138,45 @@ hs_cache_free_all(void)
digest256map_free(hs_cache_client_intro_state,
cache_client_intro_state_free_void);
hs_cache_client_intro_state = NULL;
+ hs_cache_total_allocation = 0;
+}
+
+/* Return total size of the cache. */
+size_t
+hs_cache_get_total_allocation(void)
+{
+ return hs_cache_total_allocation;
+}
+
+/** Decrement the total bytes attributed to the rendezvous cache by n. */
+void
+hs_cache_decrement_allocation(size_t n)
+{
+ static int have_underflowed = 0;
+
+ if (hs_cache_total_allocation >= n) {
+ hs_cache_total_allocation -= n;
+ } else {
+ hs_cache_total_allocation = 0;
+ if (! have_underflowed) {
+ have_underflowed = 1;
+ log_warn(LD_BUG, "Underflow in hs_cache_decrement_allocation");
+ }
+ }
+}
+
+/** Increase the total bytes attributed to the rendezvous cache by n. */
+void
+hs_cache_increment_allocation(size_t n)
+{
+ static int have_overflowed = 0;
+ if (hs_cache_total_allocation <= SIZE_MAX - n) {
+ hs_cache_total_allocation += n;
+ } else {
+ hs_cache_total_allocation = SIZE_MAX;
+ if (! have_overflowed) {
+ have_overflowed = 1;
+ log_warn(LD_BUG, "Overflow in hs_cache_increment_allocation");
+ }
+ }
}
diff --git a/src/feature/hs/hs_cache.h b/src/feature/hs/hs_cache.h
index bb3c77f224..e8165569db 100644
--- a/src/feature/hs/hs_cache.h
+++ b/src/feature/hs/hs_cache.h
@@ -21,6 +21,14 @@ struct ed25519_public_key_t;
/** This is the maximum time an introduction point state object can stay in the
* client cache in seconds (2 mins or 120 seconds). */
#define HS_CACHE_CLIENT_INTRO_STATE_MAX_AGE (2 * 60)
+/** How old do we let hidden service descriptors get before discarding
+ * them as too old? */
+#define HS_CACHE_MAX_AGE (2*24*60*60)
+/** How wrong do we assume our clock may be when checking whether hidden
+ * services are too old or too new? */
+#define HS_CACHE_MAX_SKEW (24*60*60)
+/** How old do we keep an intro point failure entry in the failure cache? */
+#define HS_CACHE_FAILURE_MAX_AGE (5*60)
/** Introduction point state. */
typedef struct hs_cache_intro_state_t {
@@ -57,7 +65,6 @@ typedef struct hs_cache_dir_descriptor_t {
/** Descriptor plaintext information. Obviously, we can't decrypt the
* encrypted part of the descriptor. */
hs_desc_plaintext_data_t *plaintext_data;
-
/** Encoded descriptor which is basically in text form. It's a NUL terminated
* string thus safe to strlen(). */
char *encoded_desc;
@@ -65,6 +72,13 @@ typedef struct hs_cache_dir_descriptor_t {
/* Public API */
+/* Return maximum lifetime in seconds of a cache entry. */
+static inline time_t
+hs_cache_max_entry_lifetime(void)
+{
+ return HS_CACHE_MAX_AGE + HS_CACHE_MAX_SKEW;
+}
+
void hs_cache_init(void);
void hs_cache_free_all(void);
void hs_cache_clean_as_dir(time_t now);
@@ -102,6 +116,10 @@ void hs_cache_client_intro_state_purge(void);
bool hs_cache_client_new_auth_parse(const ed25519_public_key_t *service_pk);
+size_t hs_cache_get_total_allocation(void);
+void hs_cache_decrement_allocation(size_t n);
+void hs_cache_increment_allocation(size_t n);
+
#ifdef HS_CACHE_PRIVATE
#include "lib/crypt_ops/crypto_ed25519.h"
diff --git a/src/feature/hs/hs_cell.c b/src/feature/hs/hs_cell.c
index 8bdaa4922a..01dd39e231 100644
--- a/src/feature/hs/hs_cell.c
+++ b/src/feature/hs/hs_cell.c
@@ -9,7 +9,6 @@
#include "core/or/or.h"
#include "app/config/config.h"
#include "lib/crypt_ops/crypto_util.h"
-#include "feature/rend/rendservice.h"
#include "feature/hs_common/replaycache.h"
#include "feature/hs/hs_cell.h"
@@ -194,37 +193,10 @@ parse_introduce2_encrypted(const uint8_t *decrypted_data,
return NULL;
}
-/** Build a legacy ESTABLISH_INTRO cell with the given circuit nonce and RSA
- * encryption key. 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 a negative value and cell_out is untouched. */
-static ssize_t
-build_legacy_establish_intro(const char *circ_nonce, crypto_pk_t *enc_key,
- uint8_t *cell_out)
-{
- ssize_t cell_len;
-
- tor_assert(circ_nonce);
- tor_assert(enc_key);
- tor_assert(cell_out);
-
- memwipe(cell_out, 0, RELAY_PAYLOAD_SIZE);
-
- cell_len = rend_service_encode_establish_intro_cell((char*)cell_out,
- RELAY_PAYLOAD_SIZE,
- enc_key, circ_nonce);
- return cell_len;
-}
-
/** Parse an INTRODUCE2 cell from payload of size payload_len for the given
* service and circuit which are used only for logging purposes. The resulting
* parsed cell is put in cell_ptr_out.
*
- * This function only parses prop224 INTRODUCE2 cells even when the intro point
- * is a legacy intro point. That's because intro points don't actually care
- * about the contents of the introduce cell. Legacy INTRODUCE cells are only
- * used by the legacy system now.
- *
* Return 0 on success else a negative value and cell_ptr_out is untouched. */
static int
parse_introduce2_cell(const hs_service_t *service,
@@ -457,28 +429,6 @@ introduce1_set_auth_key(trn_cell_introduce1_t *cell,
data->auth_pk->pubkey, trn_cell_introduce1_getlen_auth_key(cell));
}
-/** Set the legacy ID field in the INTRODUCE1 cell from the given data. */
-static void
-introduce1_set_legacy_id(trn_cell_introduce1_t *cell,
- const hs_cell_introduce1_data_t *data)
-{
- tor_assert(cell);
- tor_assert(data);
-
- if (data->is_legacy) {
- uint8_t digest[DIGEST_LEN];
- if (BUG(crypto_pk_get_digest(data->legacy_key, (char *) digest) < 0)) {
- return;
- }
- memcpy(trn_cell_introduce1_getarray_legacy_key_id(cell),
- digest, trn_cell_introduce1_getlen_legacy_key_id(cell));
- } else {
- /* We have to zeroed the LEGACY_KEY_ID field. */
- memset(trn_cell_introduce1_getarray_legacy_key_id(cell), 0,
- trn_cell_introduce1_getlen_legacy_key_id(cell));
- }
-}
-
/** Build and add to the given DoS cell extension the given parameter type and
* value. */
static void
@@ -608,8 +558,7 @@ build_establish_intro_extensions(const hs_service_config_t *service_config,
/** 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
- * a negative value and cell_out is untouched. This function also supports
- * legacy cell creation. */
+ * a negative value and cell_out is untouched. */
ssize_t
hs_cell_build_establish_intro(const char *circ_nonce,
const hs_service_config_t *service_config,
@@ -625,16 +574,6 @@ hs_cell_build_establish_intro(const char *circ_nonce,
tor_assert(service_config);
tor_assert(ip);
- /* Quickly handle the legacy IP. */
- if (ip->base.is_only_legacy) {
- tor_assert(ip->legacy_key);
- cell_len = build_legacy_establish_intro(circ_nonce, ip->legacy_key,
- cell_out);
- tor_assert(cell_len <= RELAY_PAYLOAD_SIZE);
- /* Success or not we are done here. */
- goto done;
- }
-
/* Build the extensions, if any. */
extensions = build_establish_intro_extensions(service_config, ip);
@@ -1022,9 +961,6 @@ hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data,
trn_cell_extension_set_num(ext, 0);
trn_cell_introduce1_set_extensions(cell, ext);
- /* Set the legacy ID field. */
- introduce1_set_legacy_id(cell, data);
-
/* Set the authentication key. */
introduce1_set_auth_key(cell, data);
@@ -1067,18 +1003,6 @@ hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
tor_assert(payload);
- /* If it is a legacy IP, rend-spec.txt specifies that a ACK is 0 byte and a
- * NACK is 1 byte. We can't use the legacy function for this so we have to
- * do a special case. */
- if (payload_len <= 1) {
- if (payload_len == 0) {
- ret = TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS;
- } else {
- ret = TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID;
- }
- goto end;
- }
-
if (trn_cell_introduce_ack_parse(&cell, payload, payload_len) < 0) {
log_info(LD_REND, "Invalid INTRODUCE_ACK cell. Unable to parse it.");
goto end;
diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c
index b246ab423c..548e1cbe2a 100644
--- a/src/feature/hs/hs_circuit.c
+++ b/src/feature/hs/hs_circuit.c
@@ -28,7 +28,6 @@
#include "feature/hs/hs_service.h"
#include "feature/nodelist/describe.h"
#include "feature/nodelist/nodelist.h"
-#include "feature/rend/rendservice.h"
#include "feature/stats/rephist.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_rand.h"
@@ -105,57 +104,6 @@ create_rend_cpath(const uint8_t *ntor_key_seed, size_t seed_len,
return cpath;
}
-/** We are a v2 legacy HS client: Create and return a crypt path for the hidden
- * service on the other side of the rendezvous circuit <b>circ</b>. Initialize
- * the crypt path crypto using the body of the RENDEZVOUS1 cell at
- * <b>rend_cell_body</b> (which must be at least DH1024_KEY_LEN+DIGEST_LEN
- * bytes).
- */
-static crypt_path_t *
-create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body)
-{
- crypt_path_t *hop = NULL;
- char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN];
-
- /* first DH1024_KEY_LEN bytes are g^y from the service. Finish the dh
- * handshake...*/
- tor_assert(circ->build_state);
- tor_assert(circ->build_state->pending_final_cpath);
- hop = circ->build_state->pending_final_cpath;
-
- tor_assert(hop->rend_dh_handshake_state);
- if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, hop->rend_dh_handshake_state,
- (char*)rend_cell_body, DH1024_KEY_LEN,
- keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
- log_warn(LD_GENERAL, "Couldn't complete DH handshake.");
- goto err;
- }
- /* ... and set up cpath. */
- if (cpath_init_circuit_crypto(hop,
- keys+DIGEST_LEN, sizeof(keys)-DIGEST_LEN,
- 0, 0) < 0)
- goto err;
-
- /* Check whether the digest is right... */
- if (tor_memneq(keys, rend_cell_body+DH1024_KEY_LEN, DIGEST_LEN)) {
- log_warn(LD_PROTOCOL, "Incorrect digest of key material.");
- goto err;
- }
-
- /* clean up the crypto stuff we just made */
- crypto_dh_free(hop->rend_dh_handshake_state);
- hop->rend_dh_handshake_state = NULL;
-
- goto done;
-
- err:
- hop = NULL;
-
- done:
- memwipe(keys, 0, sizeof(keys));
- return hop;
-}
-
/** Append the final <b>hop</b> to the cpath of the rend <b>circ</b>, and mark
* <b>circ</b> ready for use to transfer HS relay cells. */
static void
@@ -184,13 +132,6 @@ finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop,
/* Append the hop to the cpath of this circuit */
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
- * don't double free it. */
- if (circ->build_state) {
- circ->build_state->pending_final_cpath = NULL;
- }
-
/* Finally, mark circuit as ready to be used for client streams */
if (!is_service_side) {
circuit_try_attaching_streams(circ);
@@ -198,7 +139,7 @@ finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop,
}
/** For a given circuit and a service introduction point object, register the
- * intro circuit to the circuitmap. This supports legacy intro point. */
+ * intro circuit to the circuitmap. */
static void
register_intro_circ(const hs_service_intro_point_t *ip,
origin_circuit_t *circ)
@@ -206,13 +147,8 @@ register_intro_circ(const hs_service_intro_point_t *ip,
tor_assert(ip);
tor_assert(circ);
- if (ip->base.is_only_legacy) {
- hs_circuitmap_register_intro_circ_v2_service_side(circ,
- ip->legacy_key_digest);
- } else {
- hs_circuitmap_register_intro_circ_v3_service_side(circ,
- &ip->auth_key_kp.pubkey);
- }
+ hs_circuitmap_register_intro_circ_v3_service_side(circ,
+ &ip->auth_key_kp.pubkey);
}
/** Return the number of opened introduction circuit for the given circuit that
@@ -605,10 +541,6 @@ setup_introduce1_data(const hs_desc_intro_point_t *ip,
/* Populate the introduce1 data object. */
memset(intro1_data, 0, sizeof(hs_cell_introduce1_data_t));
- if (ip->legacy.key != NULL) {
- intro1_data->is_legacy = 1;
- intro1_data->legacy_key = ip->legacy.key;
- }
intro1_data->auth_pk = &ip->auth_key_cert->signed_key;
intro1_data->enc_pk = &ip->enc_key;
intro1_data->subcredential = subcredential;
@@ -635,8 +567,8 @@ cleanup_on_close_client_circ(circuit_t *circ)
if (circuit_is_hs_v3(circ)) {
hs_client_circuit_cleanup_on_close(circ);
}
- /* It is possible the circuit has an HS purpose but no identifier (rend_data
- * or hs_ident). Thus possible that this passes through. */
+ /* It is possible the circuit has an HS purpose but no identifier (hs_ident).
+ * Thus possible that this passes through. */
}
/** Helper: cleanup function for client circuit. This is for every HS version.
@@ -649,8 +581,8 @@ cleanup_on_free_client_circ(circuit_t *circ)
if (circuit_is_hs_v3(circ)) {
hs_client_circuit_cleanup_on_free(circ);
}
- /* It is possible the circuit has an HS purpose but no identifier (rend_data
- * or hs_ident). Thus possible that this passes through. */
+ /* It is possible the circuit has an HS purpose but no identifier (hs_ident).
+ * Thus possible that this passes through. */
}
/* ========== */
@@ -664,12 +596,7 @@ hs_circ_service_get_intro_circ(const hs_service_intro_point_t *ip)
{
tor_assert(ip);
- if (ip->base.is_only_legacy) {
- return hs_circuitmap_get_intro_circ_v2_service_side(ip->legacy_key_digest);
- } else {
- return hs_circuitmap_get_intro_circ_v3_service_side(
- &ip->auth_key_kp.pubkey);
- }
+ return hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey);
}
/** Return an introduction point established circuit matching the given intro
@@ -682,12 +609,7 @@ hs_circ_service_get_established_intro_circ(const hs_service_intro_point_t *ip)
tor_assert(ip);
- if (ip->base.is_only_legacy) {
- circ = hs_circuitmap_get_intro_circ_v2_service_side(ip->legacy_key_digest);
- } else {
- circ = hs_circuitmap_get_intro_circ_v3_service_side(
- &ip->auth_key_kp.pubkey);
- }
+ circ = hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey);
/* Only return circuit if it is established. */
return (circ && TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_INTRO) ?
@@ -695,8 +617,7 @@ hs_circ_service_get_established_intro_circ(const hs_service_intro_point_t *ip)
}
/** Called when we fail building a rendezvous circuit at some point other than
- * the last hop: launches a new circuit to the same rendezvous point. This
- * supports legacy service.
+ * the last hop: launches a new circuit to the same rendezvous point.
*
* We currently relaunch connections to rendezvous points if:
* - A rendezvous circuit timed out before connecting to RP.
@@ -726,8 +647,6 @@ hs_circ_retry_service_rendezvous_point(origin_circuit_t *circ)
/* Legacy services don't have a hidden service ident. */
if (circ->hs_ident) {
retry_service_rendezvous_point(circ);
- } else {
- rend_service_relaunch_rendezvous(circ);
}
done:
@@ -762,9 +681,7 @@ hs_circ_launch_intro_point(hs_service_t *service,
goto end;
}
/* We only use a one-hop path on the first attempt. If the first attempt
- * fails, we use a 3-hop path for reachability / reliability.
- * (Unlike v2, retries is incremented by the caller before it calls this
- * function.) */
+ * fails, we use a 3-hop path for reachability / reliability. */
if (direct_conn && ip->circuit_retries == 1) {
circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL;
}
@@ -952,10 +869,8 @@ hs_circ_handle_intro_established(const hs_service_t *service,
}
/* Try to parse the payload into a cell making sure we do actually have a
- * valid cell. For a legacy node, it's an empty payload so as long as we
- * have the cell, we are good. */
- if (!ip->base.is_only_legacy &&
- hs_cell_parse_intro_established(payload, payload_len) < 0) {
+ * valid cell. */
+ if (hs_cell_parse_intro_established(payload, payload_len) < 0) {
log_warn(LD_REND, "Unable to parse the INTRO_ESTABLISHED cell on "
"circuit %u for service %s",
TO_CIRCUIT(circ)->n_circ_id,
@@ -1112,31 +1027,6 @@ hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ,
return 0;
}
-/** We are a v2 legacy HS client and we just received a RENDEZVOUS1 cell
- * <b>rend_cell_body</b> on <b>circ</b>. Finish up the DH key exchange and then
- * extend the crypt path of <b>circ</b> so that the hidden service is on the
- * other side. */
-int
-hs_circuit_setup_e2e_rend_circ_legacy_client(origin_circuit_t *circ,
- const uint8_t *rend_cell_body)
-{
-
- if (BUG(!circuit_purpose_is_correct_for_rend(
- TO_CIRCUIT(circ)->purpose, 0))) {
- return -1;
- }
-
- crypt_path_t *hop = create_rend_cpath_legacy(circ, rend_cell_body);
- if (!hop) {
- log_warn(LD_GENERAL, "Couldn't get v2 cpath.");
- return -1;
- }
-
- finalize_rend_circuit(circ, hop, 0);
-
- return 0;
-}
-
/** Given the introduction circuit intro_circ, the rendezvous circuit
* rend_circ, a descriptor intro point object ip and the service's
* subcredential, send an INTRODUCE1 cell on intro_circ.
@@ -1381,31 +1271,20 @@ hs_circ_is_rend_sent_in_intro1(const origin_circuit_t *circ)
* confirmed rendezsvous circuit but without an introduction ACK. */
tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_REND_READY);
- /* The v2 and v3 circuit are handled differently:
- *
- * v2: A circ's pending_final_cpath field is non-NULL iff it is a rend circ
- * and we have tried to send an INTRODUCE1 cell specifying it. Thus, if the
- * pending_final_cpath field *is* NULL, then we want to not spare it.
- *
- * v3: When the INTRODUCE1 cell is sent, the introduction encryption public
+ /* When the INTRODUCE1 cell is sent, the introduction encryption public
* key is copied in the rendezvous circuit hs identifier. If it is a valid
* key, we know that this circuit is waiting the ACK on the introduction
* circuit. We want to _not_ spare the circuit if the key was never set. */
- if (circ->rend_data) {
- /* v2. */
- if (circ->build_state && circ->build_state->pending_final_cpath != NULL) {
- return true;
- }
- } else if (circ->hs_ident) {
+ if (circ->hs_ident) {
/* v3. */
if (curve25519_public_key_is_ok(&circ->hs_ident->intro_enc_pk)) {
return true;
}
} else {
- /* A circuit with an HS purpose without an hs_ident or rend_data in theory
- * can not happen. In case, scream loudly and return false to the caller
- * that the rendezvous was not sent in the INTRO1 cell. */
+ /* A circuit with an HS purpose without an hs_ident in theory can not
+ * happen. In case, scream loudly and return false to the caller that the
+ * rendezvous was not sent in the INTRO1 cell. */
tor_assert_nonfatal_unreached();
}
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index 28bbe72459..f1c17f4f90 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -1950,11 +1950,6 @@ hs_client_note_connection_attempt_succeeded(const edge_connection_t *conn)
{
tor_assert(connection_edge_is_rendezvous_stream(conn));
- if (BUG(conn->rend_data && conn->hs_ident)) {
- log_warn(LD_BUG, "Stream had both rend_data and hs_ident..."
- "Prioritizing hs_ident");
- }
-
if (conn->hs_ident) { /* It's v3: pass it to the prop224 handler */
note_connection_attempt_succeeded(conn->hs_ident);
return;
@@ -2094,8 +2089,6 @@ hs_client_circuit_has_opened(origin_circuit_t *circ)
{
tor_assert(circ);
- /* Handle both version. v2 uses rend_data and v3 uses the hs circuit
- * identifier hs_ident. Can't be both. */
switch (TO_CIRCUIT(circ)->purpose) {
case CIRCUIT_PURPOSE_C_INTRODUCING:
if (circ->hs_ident) {
diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c
index 55cc4d5518..ae4a9cd970 100644
--- a/src/feature/hs/hs_common.c
+++ b/src/feature/hs/hs_common.c
@@ -33,7 +33,6 @@
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"
#include "feature/rend/rendcommon.h"
-#include "feature/rend/rendservice.h"
#include "feature/relay/routermode.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
@@ -337,258 +336,6 @@ hs_get_start_time_of_next_time_period(time_t now)
return (time_t)(start_of_next_tp_in_mins * 60 + time_period_rotation_offset);
}
-/** Create a new rend_data_t for a specific given <b>version</b>.
- * Return a pointer to the newly allocated data structure. */
-static rend_data_t *
-rend_data_alloc(uint32_t version)
-{
- rend_data_t *rend_data = NULL;
-
- switch (version) {
- case HS_VERSION_TWO:
- {
- rend_data_v2_t *v2 = tor_malloc_zero(sizeof(*v2));
- v2->base_.version = HS_VERSION_TWO;
- v2->base_.hsdirs_fp = smartlist_new();
- rend_data = &v2->base_;
- break;
- }
- default:
- tor_assert(0);
- break;
- }
-
- return rend_data;
-}
-
-/** Free all storage associated with <b>data</b> */
-void
-rend_data_free_(rend_data_t *data)
-{
- if (!data) {
- return;
- }
- /* By using our allocation function, this should always be set. */
- tor_assert(data->hsdirs_fp);
- /* Cleanup the HSDir identity digest. */
- SMARTLIST_FOREACH(data->hsdirs_fp, char *, d, tor_free(d));
- smartlist_free(data->hsdirs_fp);
- /* Depending on the version, cleanup. */
- switch (data->version) {
- case HS_VERSION_TWO:
- {
- rend_data_v2_t *v2_data = TO_REND_DATA_V2(data);
- tor_free(v2_data);
- break;
- }
- default:
- tor_assert(0);
- }
-}
-
-/** Allocate and return a deep copy of <b>data</b>. */
-rend_data_t *
-rend_data_dup(const rend_data_t *data)
-{
- rend_data_t *data_dup = NULL;
- smartlist_t *hsdirs_fp = smartlist_new();
-
- tor_assert(data);
- tor_assert(data->hsdirs_fp);
-
- SMARTLIST_FOREACH(data->hsdirs_fp, char *, fp,
- smartlist_add(hsdirs_fp, tor_memdup(fp, DIGEST_LEN)));
-
- switch (data->version) {
- case HS_VERSION_TWO:
- {
- rend_data_v2_t *v2_data = tor_memdup(TO_REND_DATA_V2(data),
- sizeof(*v2_data));
- data_dup = &v2_data->base_;
- data_dup->hsdirs_fp = hsdirs_fp;
- break;
- }
- default:
- tor_assert(0);
- break;
- }
-
- return data_dup;
-}
-
-/** Compute the descriptor ID for each HS descriptor replica and save them. A
- * valid onion address must be present in the <b>rend_data</b>.
- *
- * Return 0 on success else -1. */
-static int
-compute_desc_id(rend_data_t *rend_data)
-{
- int ret = 0;
- unsigned replica;
- time_t now = time(NULL);
-
- tor_assert(rend_data);
-
- switch (rend_data->version) {
- case HS_VERSION_TWO:
- {
- rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data);
- /* Compute descriptor ID for each replicas. */
- for (replica = 0; replica < ARRAY_LENGTH(v2_data->descriptor_id);
- replica++) {
- ret = rend_compute_v2_desc_id(v2_data->descriptor_id[replica],
- v2_data->onion_address,
- v2_data->descriptor_cookie,
- now, replica);
- if (ret < 0) {
- goto end;
- }
- }
- break;
- }
- default:
- tor_assert(0);
- }
-
- end:
- return ret;
-}
-
-/** Allocate and initialize a rend_data_t object for a service using the
- * provided arguments. All arguments are optional (can be NULL), except from
- * <b>onion_address</b> which MUST be set. The <b>pk_digest</b> is the hash of
- * the service private key. The <b>cookie</b> is the rendezvous cookie and
- * <b>auth_type</b> is which authentiation this service is configured with.
- *
- * Return a valid rend_data_t pointer. This only returns a version 2 object of
- * rend_data_t. */
-rend_data_t *
-rend_data_service_create(const char *onion_address, const char *pk_digest,
- const uint8_t *cookie, rend_auth_type_t auth_type)
-{
- /* Create a rend_data_t object for version 2. */
- rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO);
- rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data);
-
- /* We need at least one else the call is wrong. */
- tor_assert(onion_address != NULL);
-
- if (pk_digest) {
- memcpy(v2->rend_pk_digest, pk_digest, sizeof(v2->rend_pk_digest));
- }
- if (cookie) {
- memcpy(rend_data->rend_cookie, cookie, sizeof(rend_data->rend_cookie));
- }
-
- strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address));
- v2->auth_type = auth_type;
-
- return rend_data;
-}
-
-/** Allocate and initialize a rend_data_t object for a client request using the
- * given arguments. Either an onion address or a descriptor ID is needed. Both
- * can be given but in this case only the onion address will be used to make
- * the descriptor fetch. The <b>cookie</b> is the rendezvous cookie and
- * <b>auth_type</b> is which authentiation the service is configured with.
- *
- * Return a valid rend_data_t pointer or NULL on error meaning the
- * descriptor IDs couldn't be computed from the given data. */
-rend_data_t *
-rend_data_client_create(const char *onion_address, const char *desc_id,
- const char *cookie, rend_auth_type_t auth_type)
-{
- /* Create a rend_data_t object for version 2. */
- rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO);
- rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data);
-
- /* We need at least one else the call is wrong. */
- tor_assert(onion_address != NULL || desc_id != NULL);
-
- if (cookie) {
- memcpy(v2->descriptor_cookie, cookie, sizeof(v2->descriptor_cookie));
- }
- if (desc_id) {
- memcpy(v2->desc_id_fetch, desc_id, sizeof(v2->desc_id_fetch));
- }
- if (onion_address) {
- strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address));
- if (compute_desc_id(rend_data) < 0) {
- goto error;
- }
- }
-
- v2->auth_type = auth_type;
-
- return rend_data;
-
- error:
- rend_data_free(rend_data);
- return NULL;
-}
-
-/** Return the onion address from the rend data. Depending on the version,
- * the size of the address can vary but it's always NUL terminated. */
-const char *
-rend_data_get_address(const rend_data_t *rend_data)
-{
- tor_assert(rend_data);
-
- switch (rend_data->version) {
- case HS_VERSION_TWO:
- return TO_REND_DATA_V2(rend_data)->onion_address;
- default:
- /* We should always have a supported version. */
- tor_assert_unreached();
- }
-}
-
-/** Return the descriptor ID for a specific replica number from the rend
- * data. The returned data is a binary digest and depending on the version its
- * size can vary. The size of the descriptor ID is put in <b>len_out</b> if
- * non NULL. */
-const char *
-rend_data_get_desc_id(const rend_data_t *rend_data, uint8_t replica,
- size_t *len_out)
-{
- tor_assert(rend_data);
-
- switch (rend_data->version) {
- case HS_VERSION_TWO:
- tor_assert(replica < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS);
- if (len_out) {
- *len_out = DIGEST_LEN;
- }
- return TO_REND_DATA_V2(rend_data)->descriptor_id[replica];
- default:
- /* We should always have a supported version. */
- tor_assert_unreached();
- }
-}
-
-/** Return the public key digest using the given <b>rend_data</b>. The size of
- * the digest is put in <b>len_out</b> (if set) which can differ depending on
- * the version. */
-const uint8_t *
-rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out)
-{
- tor_assert(rend_data);
-
- switch (rend_data->version) {
- case HS_VERSION_TWO:
- {
- const rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data);
- if (len_out) {
- *len_out = sizeof(v2_data->rend_pk_digest);
- }
- return (const uint8_t *) v2_data->rend_pk_digest;
- }
- default:
- /* We should always have a supported version. */
- tor_assert_unreached();
- }
-}
-
/** Using the given time period number, compute the disaster shared random
* value and put it in srv_out. It MUST be at least DIGEST256_LEN bytes. */
static void
@@ -1981,9 +1728,7 @@ hs_dec_rdv_stream_counter(origin_circuit_t *circ)
{
tor_assert(circ);
- if (circ->rend_data) {
- circ->rend_data->nr_streams--;
- } else if (circ->hs_ident) {
+ if (circ->hs_ident) {
circ->hs_ident->num_rdv_streams--;
} else {
/* Should not be called if this circuit is not for hidden service. */
@@ -1998,9 +1743,7 @@ hs_inc_rdv_stream_counter(origin_circuit_t *circ)
{
tor_assert(circ);
- if (circ->rend_data) {
- circ->rend_data->nr_streams++;
- } else if (circ->hs_ident) {
+ if (circ->hs_ident) {
circ->hs_ident->num_rdv_streams++;
} else {
/* Should not be called if this circuit is not for hidden service. */
diff --git a/src/feature/hs/hs_common.h b/src/feature/hs/hs_common.h
index 894b0e4844..5ddc6fd2d8 100644
--- a/src/feature/hs/hs_common.h
+++ b/src/feature/hs/hs_common.h
@@ -19,13 +19,10 @@ struct ed25519_keypair_t;
/* Trunnel */
#include "trunnel/ed25519_cert.h"
-/** Protocol version 2. Use this instead of hardcoding "2" in the code base,
- * this adds a clearer semantic to the value when used. */
-#define HS_VERSION_TWO 2
/** Version 3 of the protocol (prop224). */
#define HS_VERSION_THREE 3
/** Earliest version we support. */
-#define HS_VERSION_MIN HS_VERSION_TWO
+#define HS_VERSION_MIN HS_VERSION_THREE
/** Latest version we support. */
#define HS_VERSION_MAX HS_VERSION_THREE
@@ -194,24 +191,6 @@ void hs_build_blinded_keypair(const struct ed25519_keypair_t *kp,
struct ed25519_keypair_t *kp_out);
int hs_service_requires_uptime_circ(const smartlist_t *ports);
-void rend_data_free_(rend_data_t *data);
-#define rend_data_free(data) \
- FREE_AND_NULL(rend_data_t, rend_data_free_, (data))
-rend_data_t *rend_data_dup(const rend_data_t *data);
-rend_data_t *rend_data_client_create(const char *onion_address,
- const char *desc_id,
- const char *cookie,
- rend_auth_type_t auth_type);
-rend_data_t *rend_data_service_create(const char *onion_address,
- const char *pk_digest,
- const uint8_t *cookie,
- rend_auth_type_t auth_type);
-const char *rend_data_get_address(const rend_data_t *rend_data);
-const char *rend_data_get_desc_id(const rend_data_t *rend_data,
- uint8_t replica, size_t *len_out);
-const uint8_t *rend_data_get_pk_digest(const rend_data_t *rend_data,
- size_t *len_out);
-
routerstatus_t *pick_hsdir(const char *desc_id, const char *desc_id_base32);
struct hs_subcredential_t;
diff --git a/src/feature/hs/hs_config.c b/src/feature/hs/hs_config.c
index b100acfcd4..e2e1756f21 100644
--- a/src/feature/hs/hs_config.c
+++ b/src/feature/hs/hs_config.c
@@ -28,7 +28,6 @@
#include "feature/hs/hs_client.h"
#include "feature/hs/hs_ob.h"
#include "feature/hs/hs_service.h"
-#include "feature/rend/rendservice.h"
#include "lib/encoding/confline.h"
#include "lib/conf/confdecl.h"
#include "lib/confmgt/confmgt.h"
@@ -101,23 +100,6 @@ stage_services(smartlist_t *service_list)
{
tor_assert(service_list);
- /* This is v2 specific. Trigger service pruning which will make sure the
- * just configured services end up in the main global list. It should only
- * be done in non validation mode because v2 subsystem handles service
- * object differently. */
- rend_service_prune_list();
-
- /* Cleanup v2 service from the list, we don't need those object anymore
- * because we validated them all against the others and we want to stage
- * only >= v3 service. And remember, v2 has a different object type which is
- * shadow copied from an hs_service_t type. */
- SMARTLIST_FOREACH_BEGIN(service_list, hs_service_t *, s) {
- if (s->config.version == HS_VERSION_TWO) {
- SMARTLIST_DEL_CURRENT(service_list, s);
- hs_service_free(s);
- }
- } SMARTLIST_FOREACH_END(s);
-
/* This is >= v3 specific. Using the newly configured service list, stage
* them into our global state. Every object ownership is lost after. */
hs_service_stage_services(service_list);
@@ -145,8 +127,7 @@ service_is_duplicate_in_list(const smartlist_t *service_list,
/* XXX: Validate if we have any service that has the given service dir path.
* This has two problems:
*
- * a) It's O(n^2), but the same comment from the bottom of
- * rend_config_services() should apply.
+ * a) It's O(n^2)
*
* b) We only compare directory paths as strings, so we can't
* detect two distinct paths that specify the same directory
@@ -269,15 +250,6 @@ config_has_invalid_options(const config_line_t *line_,
NULL /* End marker. */
};
- const char *opts_exclude_v2[] = {
- "HiddenServiceExportCircuitID",
- "HiddenServiceEnableIntroDoSDefense",
- "HiddenServiceEnableIntroDoSRatePerSec",
- "HiddenServiceEnableIntroDoSBurstPerSec",
- "HiddenServiceOnionBalanceInstance",
- NULL /* End marker. */
- };
-
/* Defining the size explicitly allows us to take advantage of the compiler
* which warns us if we ever bump the max version but forget to grow this
* array. The plus one is because we have a version 0 :). */
@@ -286,7 +258,7 @@ config_has_invalid_options(const config_line_t *line_,
} exclude_lists[HS_VERSION_MAX + 1] = {
{ NULL }, /* v0. */
{ NULL }, /* v1. */
- { opts_exclude_v2 }, /* v2 */
+ { NULL }, /* v2. */
{ opts_exclude_v3 }, /* v3. */
};
@@ -310,16 +282,6 @@ config_has_invalid_options(const config_line_t *line_,
"version %" PRIu32 " of service in %s",
opt, service->config.version,
service->config.directory_path);
-
- if (!strcasecmp(line->key, "HiddenServiceAuthorizeClient")) {
- /* Special case this v2 option so that we can offer alternatives.
- * If more such special cases appear, it would be good to
- * generalize the exception mechanism here. */
- log_warn(LD_CONFIG, "For v3 onion service client authorization, "
- "please read the 'CLIENT AUTHORIZATION' section in the "
- "manual.");
- }
-
ret = 1;
/* Continue the loop so we can find all possible options. */
continue;
@@ -521,7 +483,7 @@ config_generic_service(const hs_opts_t *hs_opts,
/* Check if we are configured in non anonymous mode meaning every service
* becomes a single onion service. */
- if (rend_service_non_anonymous_mode_enabled(options)) {
+ if (hs_service_non_anonymous_mode_enabled(options)) {
config->is_single_onion = 1;
}
@@ -594,8 +556,7 @@ config_service(config_line_t *line, const or_options_t *options,
service->config.version = config_learn_service_version(service);
}
- /* We make sure that this set of options for a service are valid that is for
- * instance an option only for v2 is not used for v3. */
+ /* We make sure that this set of options for a service are valid. */
if (config_has_invalid_options(line->next, service)) {
goto err;
}
@@ -604,9 +565,6 @@ config_service(config_line_t *line, const or_options_t *options,
* start just after the service directory line so once we hit another
* directory line, the function knows that it has to stop parsing. */
switch (service->config.version) {
- case HS_VERSION_TWO:
- ret = rend_config_service(hs_opts, options, &service->config);
- break;
case HS_VERSION_THREE:
ret = config_service_v3(hs_opts, &service->config);
break;
@@ -687,11 +645,6 @@ hs_config_service_all(const or_options_t *options, int validate_only)
* services. We don't need those objects anymore. */
SMARTLIST_FOREACH(new_service_list, hs_service_t *, s,
hs_service_free(s));
- /* For the v2 subsystem, the configuration function adds the service
- * object to the staging list and it is transferred in the main list
- * through the prunning process. In validation mode, we thus have to purge
- * the staging list so it's not kept in memory as valid service. */
- rend_service_free_staging_list();
}
/* Success. Note that the service list has no ownership of its content. */
diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c
index 0656224e48..0faa91f871 100644
--- a/src/feature/hs/hs_descriptor.c
+++ b/src/feature/hs/hs_descriptor.c
@@ -64,7 +64,6 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "feature/dirparse/parsecommon.h"
-#include "feature/rend/rendcache.h"
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_config.h"
#include "feature/nodelist/torcert.h" /* tor_cert_encode_ed22519() */
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index b33013ba1f..79734a67d5 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -29,7 +29,6 @@
#include "feature/nodelist/nickname.h"
#include "feature/nodelist/node_select.h"
#include "feature/nodelist/nodelist.h"
-#include "feature/rend/rendservice.h"
#include "lib/crypt_ops/crypto_ope.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
@@ -2666,8 +2665,6 @@ run_housekeeping_event(time_t now)
static void
run_build_descriptor_event(time_t now)
{
- /* For v2 services, this step happens in the upload event. */
-
/* Run v3+ events. */
/* We start by rotating the descriptors only if needed. */
rotate_all_descriptors(now);
@@ -2840,11 +2837,6 @@ run_build_circuit_event(time_t now)
return;
}
- /* Run v2 check. */
- if (rend_num_services() > 0) {
- rend_consider_services_intro_points(now);
- }
-
/* Run v3+ check. */
FOR_EACH_SERVICE_BEGIN(service) {
/* For introduction circuit, we need to make sure we don't stress too much
@@ -3280,13 +3272,6 @@ refresh_service_descriptor(const hs_service_t *service,
STATIC void
run_upload_descriptor_event(time_t now)
{
- /* v2 services use the same function for descriptor creation and upload so
- * we do everything here because the intro circuits were checked before. */
- if (rend_num_services() > 0) {
- rend_consider_services_upload(now);
- rend_consider_descriptor_republication();
- }
-
/* Run v3+ check. */
FOR_EACH_SERVICE_BEGIN(service) {
FOR_EACH_DESCRIPTOR_BEGIN(service, desc) {
@@ -3615,6 +3600,54 @@ service_encode_descriptor(const hs_service_t *service,
/* Public API */
/* ========== */
+/* Are HiddenServiceSingleHopMode and HiddenServiceNonAnonymousMode consistent?
+ */
+static int
+hs_service_non_anonymous_mode_consistent(const or_options_t *options)
+{
+ /* !! is used to make these options boolean */
+ return (!! options->HiddenServiceSingleHopMode ==
+ !! options->HiddenServiceNonAnonymousMode);
+}
+
+/* Do the options allow onion services to make direct (non-anonymous)
+ * connections to introduction or rendezvous points?
+ * Must only be called after options_validate_single_onion() has successfully
+ * checked onion service option consistency.
+ * Returns true if tor is in HiddenServiceSingleHopMode. */
+int
+hs_service_allow_non_anonymous_connection(const or_options_t *options)
+{
+ tor_assert(hs_service_non_anonymous_mode_consistent(options));
+ return options->HiddenServiceSingleHopMode ? 1 : 0;
+}
+
+/* Do the options allow us to reveal the exact startup time of the onion
+ * service?
+ * Single Onion Services prioritise availability over hiding their
+ * startup time, as their IP address is publicly discoverable anyway.
+ * Must only be called after options_validate_single_onion() has successfully
+ * checked onion service option consistency.
+ * Returns true if tor is in non-anonymous hidden service mode. */
+int
+hs_service_reveal_startup_time(const or_options_t *options)
+{
+ tor_assert(hs_service_non_anonymous_mode_consistent(options));
+ return hs_service_non_anonymous_mode_enabled(options);
+}
+
+/* Is non-anonymous mode enabled using the HiddenServiceNonAnonymousMode
+ * config option?
+ * Must only be called after options_validate_single_onion() has successfully
+ * checked onion service option consistency.
+ */
+int
+hs_service_non_anonymous_mode_enabled(const or_options_t *options)
+{
+ tor_assert(hs_service_non_anonymous_mode_consistent(options));
+ return options->HiddenServiceNonAnonymousMode ? 1 : 0;
+}
+
/** Called when a circuit was just cleaned up. This is done right before the
* circuit is marked for close. */
void
@@ -3641,7 +3674,7 @@ hs_service_circuit_cleanup_on_close(const circuit_t *circ)
}
}
-/** This is called every time the service map (v2 or v3) changes that is if an
+/** This is called every time the service map changes that is if an
* element is added or removed. */
void
hs_service_map_has_changed(void)
@@ -3992,9 +4025,6 @@ hs_service_lists_fnames_for_sandbox(smartlist_t *file_list,
tor_assert(file_list);
tor_assert(dir_list);
- /* Add files and dirs for legacy services. */
- rend_services_add_filenames_to_lists(file_list, dir_list);
-
/* Add files and dirs for v3+. */
FOR_EACH_SERVICE_BEGIN(service) {
/* Skip ephemeral service, they don't touch the disk. */
@@ -4046,9 +4076,6 @@ hs_service_receive_introduce2(origin_circuit_t *circ, const uint8_t *payload,
if (circ->hs_ident) {
ret = service_handle_introduce2(circ, payload, payload_len);
hs_stats_note_introduce2_cell(1);
- } else {
- ret = rend_service_receive_introduction(circ, payload, payload_len);
- hs_stats_note_introduce2_cell(0);
}
done:
@@ -4075,12 +4102,8 @@ hs_service_receive_intro_established(origin_circuit_t *circ,
goto err;
}
- /* Handle both version. v2 uses rend_data and v3 uses the hs circuit
- * identifier hs_ident. Can't be both. */
if (circ->hs_ident) {
ret = service_handle_intro_established(circ, payload, payload_len);
- } else {
- ret = rend_service_intro_established(circ, payload, payload_len);
}
if (ret < 0) {
@@ -4099,21 +4122,15 @@ hs_service_circuit_has_opened(origin_circuit_t *circ)
{
tor_assert(circ);
- /* Handle both version. v2 uses rend_data and v3 uses the hs circuit
- * identifier hs_ident. Can't be both. */
switch (TO_CIRCUIT(circ)->purpose) {
case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
if (circ->hs_ident) {
service_intro_circ_has_opened(circ);
- } else {
- rend_service_intro_has_opened(circ);
}
break;
case CIRCUIT_PURPOSE_S_CONNECT_REND:
if (circ->hs_ident) {
service_rendezvous_circ_has_opened(circ);
- } else {
- rend_service_rendezvous_has_opened(circ);
}
break;
default:
@@ -4141,11 +4158,6 @@ hs_service_get_version_from_key(const hs_service_t *service)
version = HS_VERSION_THREE;
goto end;
}
- /* Version 2 check. */
- if (rend_service_key_on_disk(directory_path)) {
- version = HS_VERSION_TWO;
- goto end;
- }
end:
return version;
@@ -4156,13 +4168,6 @@ hs_service_get_version_from_key(const hs_service_t *service)
int
hs_service_load_all_keys(void)
{
- /* Load v2 service keys if we have v2. */
- if (rend_num_services() != 0) {
- if (rend_service_load_all_keys(NULL) < 0) {
- goto err;
- }
- }
-
/* Load or/and generate them for v3+. */
SMARTLIST_FOREACH_BEGIN(hs_service_staging_list, hs_service_t *, service) {
/* Ignore ephemeral service, they already have their keys set. */
@@ -4362,9 +4367,6 @@ hs_service_init(void)
tor_assert(!hs_service_map);
tor_assert(!hs_service_staging_list);
- /* v2 specific. */
- rend_service_init();
-
hs_service_map = tor_malloc_zero(sizeof(struct hs_service_ht));
HT_INIT(hs_service_ht, hs_service_map);
@@ -4375,7 +4377,6 @@ hs_service_init(void)
void
hs_service_free_all(void)
{
- rend_service_free_all();
service_free_all();
hs_config_free_all();
}
diff --git a/src/feature/hs/hs_service.h b/src/feature/hs/hs_service.h
index 54d646d3e4..be01ce3cfb 100644
--- a/src/feature/hs/hs_service.h
+++ b/src/feature/hs/hs_service.h
@@ -398,6 +398,11 @@ service_authorized_client_free_(hs_service_authorized_client_t *client);
FREE_AND_NULL(hs_service_authorized_client_t, \
service_authorized_client_free_, (c))
+/* Config options. */
+int hs_service_allow_non_anonymous_connection(const or_options_t *options);
+int hs_service_non_anonymous_mode_enabled(const or_options_t *options);
+int hs_service_reveal_startup_time(const or_options_t *options);
+
#ifdef HS_SERVICE_PRIVATE
#ifdef TOR_UNIT_TESTS