summaryrefslogtreecommitdiff
path: root/src/feature
diff options
context:
space:
mode:
Diffstat (limited to 'src/feature')
-rw-r--r--src/feature/client/entrynodes.c3
-rw-r--r--src/feature/control/control_cmd.c32
-rw-r--r--src/feature/control/control_getinfo.c32
-rw-r--r--src/feature/dircache/dircache.c98
-rw-r--r--src/feature/dircache/dircache.h2
-rw-r--r--src/feature/dirclient/dirclient.c42
-rw-r--r--src/feature/dircommon/directory.h6
-rw-r--r--src/feature/hs/hs_cache.c61
-rw-r--r--src/feature/hs/hs_common.h2
-rw-r--r--src/feature/hs/hs_config.c8
-rw-r--r--src/feature/hs/hs_descriptor.c3
-rw-r--r--src/feature/hs/hs_intropoint.c3
-rw-r--r--src/feature/relay/dns.c9
-rw-r--r--src/feature/relay/router.c23
-rw-r--r--src/feature/relay/router.h1
15 files changed, 160 insertions, 165 deletions
diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c
index 232216c521..82866ea668 100644
--- a/src/feature/client/entrynodes.c
+++ b/src/feature/client/entrynodes.c
@@ -804,9 +804,6 @@ get_sampled_guard_for_bridge(guard_selection_t *gs,
entry_guard_t *guard;
if (BUG(!addrport))
return NULL; // LCOV_EXCL_LINE
- if (bridge_has_invalid_transport(bridge)) {
- return NULL;
- }
guard = get_sampled_guard_by_bridge_addr(gs, addrport);
if (! guard || (id && tor_memneq(id, guard->identity, DIGEST_LEN)))
return NULL;
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c
index 0456d709f5..b4d7228b51 100644
--- a/src/feature/control/control_cmd.c
+++ b/src/feature/control/control_cmd.c
@@ -1443,10 +1443,8 @@ handle_control_hsfetch(control_connection_t *conn,
const control_cmd_args_t *args)
{
- char digest[DIGEST_LEN], *desc_id = NULL;
+ char *desc_id = NULL;
smartlist_t *hsdirs = NULL;
- static const char *v2_str = "v2-";
- const size_t v2_str_len = strlen(v2_str);
rend_data_t *rend_query = NULL;
ed25519_public_key_t v3_pk;
uint32_t version;
@@ -1454,20 +1452,7 @@ handle_control_hsfetch(control_connection_t *conn,
/* Extract the first argument (either HSAddress or DescID). */
const char *arg1 = smartlist_get(args->args, 0);
- /* Test if it's an HS address without the .onion part. */
- if (rend_valid_v2_service_id(arg1)) {
- hsaddress = arg1;
- version = HS_VERSION_TWO;
- } else if (strcmpstart(arg1, v2_str) == 0 &&
- rend_valid_descriptor_id(arg1 + v2_str_len) &&
- base32_decode(digest, sizeof(digest), arg1 + v2_str_len,
- REND_DESC_ID_V2_LEN_BASE32) ==
- sizeof(digest)) {
- /* We have a well formed version 2 descriptor ID. Keep the decoded value
- * of the id. */
- desc_id = digest;
- version = HS_VERSION_TWO;
- } else if (hs_address_is_valid(arg1)) {
+ if (hs_address_is_valid(arg1)) {
hsaddress = arg1;
version = HS_VERSION_THREE;
hs_parse_address(hsaddress, &v3_pk, NULL, NULL);
@@ -1590,6 +1575,11 @@ handle_control_hspost(control_connection_t *conn,
goto done;
}
+ /* As for HSFETCH, we no longer support v2 on the network and so we stop
+ * right now. Code is not removed in order to minimize the merge forward
+ * conflicts. */
+ goto done;
+
/* From this point on, it is only v2. */
/* parse it. */
@@ -1662,11 +1652,13 @@ add_onion_helper_add_service(int hs_version,
tor_assert(port_cfgs);
tor_assert(address_out);
+ /* Version 2 is disabled. */
+ (void) auth_type;
+ (void) auth_clients;
+
switch (hs_version) {
case HS_VERSION_TWO:
- ret = rend_service_add_ephemeral(pk->v2, port_cfgs, max_streams,
- max_streams_close_circuit, auth_type,
- auth_clients, address_out);
+ ret = RSAE_INTERNAL;
break;
case HS_VERSION_THREE:
ret = hs_service_add_ephemeral(pk->v3, port_cfgs, max_streams,
diff --git a/src/feature/control/control_getinfo.c b/src/feature/control/control_getinfo.c
index 5feadd23d1..899f188546 100644
--- a/src/feature/control/control_getinfo.c
+++ b/src/feature/control/control_getinfo.c
@@ -353,26 +353,24 @@ getinfo_helper_current_consensus(consensus_flavor_t flavor,
*errmsg = "Internal error: unrecognized flavor name.";
return -1;
}
- if (we_want_to_fetch_flavor(get_options(), flavor)) {
- /** Check from the cache */
- const cached_dir_t *consensus = dirserv_get_consensus(flavor_name);
- if (consensus) {
- *answer = tor_strdup(consensus->dir);
- }
+ tor_mmap_t *mapped = networkstatus_map_cached_consensus(flavor_name);
+ if (mapped) {
+ *answer = tor_memdup_nulterm(mapped->data, mapped->size);
+ tor_munmap_file(mapped);
}
- if (!*answer) { /* try loading it from disk */
-
- tor_mmap_t *mapped = networkstatus_map_cached_consensus(flavor_name);
- if (mapped) {
- *answer = tor_memdup_nulterm(mapped->data, mapped->size);
- tor_munmap_file(mapped);
- }
- if (!*answer) { /* generate an error */
- *errmsg = "Could not open cached consensus. "
- "Make sure FetchUselessDescriptors is set to 1.";
- return -1;
+ if (!*answer) { /* Maybe it's in the cache? */
+ if (we_want_to_fetch_flavor(get_options(), flavor)) {
+ const cached_dir_t *consensus = dirserv_get_consensus(flavor_name);
+ if (consensus) {
+ *answer = tor_strdup(consensus->dir);
+ }
}
}
+ if (!*answer) { /* generate an error */
+ *errmsg = "Could not open cached consensus. "
+ "Make sure FetchUselessDescriptors is set to 1.";
+ return -1;
+ }
return 0;
}
diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c
index 00bb0abf23..2af550a760 100644
--- a/src/feature/dircache/dircache.c
+++ b/src/feature/dircache/dircache.c
@@ -296,19 +296,22 @@ client_likes_consensus(const struct consensus_cache_entry_t *ent,
/** Return the compression level we should use for sending a compressed
* response of size <b>n_bytes</b>. */
STATIC compression_level_t
-choose_compression_level(ssize_t n_bytes)
+choose_compression_level(void)
{
- if (! have_been_under_memory_pressure()) {
- return HIGH_COMPRESSION; /* we have plenty of RAM. */
- } else if (n_bytes < 0) {
- return HIGH_COMPRESSION; /* unknown; might be big. */
- } else if (n_bytes < 1024) {
- return LOW_COMPRESSION;
- } else if (n_bytes < 2048) {
- return MEDIUM_COMPRESSION;
- } else {
- return HIGH_COMPRESSION;
- }
+ /* This is the compression level choice for a stream.
+ *
+ * We always return LOW because this compression is done in the main thread
+ * thus we save CPU time as much as possible, and it is also done more than
+ * background compression for document we serve pre-compressed.
+ *
+ * GZip highest compression level (9) gives us a ratio of 49.72%
+ * Zstd lowest compression level (1) gives us a ratio of 47.38%
+ *
+ * Thus, as the network moves more and more to use Zstd when requesting
+ * directory documents that are not pre-cached, even at the
+ * lowest level, we still gain over GZip and thus help with load and CPU
+ * time on the network. */
+ return LOW_COMPRESSION;
}
/** Information passed to handle a GET request. */
@@ -353,8 +356,6 @@ static int handle_get_descriptor(dir_connection_t *conn,
const get_handler_args_t *args);
static int handle_get_keys(dir_connection_t *conn,
const get_handler_args_t *args);
-static int handle_get_hs_descriptor_v2(dir_connection_t *conn,
- const get_handler_args_t *args);
static int handle_get_robots(dir_connection_t *conn,
const get_handler_args_t *args);
static int handle_get_networkstatus_bridges(dir_connection_t *conn,
@@ -373,7 +374,6 @@ static const url_table_ent_t url_table[] = {
{ "/tor/server/", 1, handle_get_descriptor },
{ "/tor/extra/", 1, handle_get_descriptor },
{ "/tor/keys/", 1, handle_get_keys },
- { "/tor/rendezvous2/", 1, handle_get_hs_descriptor_v2 },
{ "/tor/hs/3/", 1, handle_get_hs_descriptor_v3 },
{ "/tor/robots.txt", 0, handle_get_robots },
{ "/tor/networkstatus-bridges", 0, handle_get_networkstatus_bridges },
@@ -1078,7 +1078,7 @@ handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args)
if (smartlist_len(items)) {
if (compress_method != NO_METHOD) {
conn->compress_state = tor_compress_new(1, compress_method,
- choose_compression_level(estimated_len));
+ choose_compression_level());
}
SMARTLIST_FOREACH(items, const char *, c,
@@ -1141,7 +1141,7 @@ handle_get_microdesc(dir_connection_t *conn, const get_handler_args_t *args)
if (compress_method != NO_METHOD)
conn->compress_state = tor_compress_new(1, compress_method,
- choose_compression_level(size_guess));
+ choose_compression_level());
const int initial_flush_result = connection_dirserv_flushed_some(conn);
tor_assert_nonfatal(initial_flush_result == 0);
@@ -1236,7 +1236,7 @@ handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args)
write_http_response_header(conn, -1, compress_method, cache_lifetime);
if (compress_method != NO_METHOD)
conn->compress_state = tor_compress_new(1, compress_method,
- choose_compression_level(size_guess));
+ choose_compression_level());
clear_spool = 0;
/* Prime the connection with some data. */
int initial_flush_result = connection_dirserv_flushed_some(conn);
@@ -1332,7 +1332,7 @@ handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args)
60*60);
if (compress_method != NO_METHOD) {
conn->compress_state = tor_compress_new(1, compress_method,
- choose_compression_level(len));
+ choose_compression_level());
}
SMARTLIST_FOREACH(certs, authority_cert_t *, c,
@@ -1347,45 +1347,7 @@ handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args)
return 0;
}
-/** Helper function for GET /tor/rendezvous2/
- */
-static int
-handle_get_hs_descriptor_v2(dir_connection_t *conn,
- const get_handler_args_t *args)
-{
- const char *url = args->url;
- if (connection_dir_is_encrypted(conn)) {
- /* Handle v2 rendezvous descriptor fetch request. */
- const char *descp;
- const char *query = url + strlen("/tor/rendezvous2/");
- if (rend_valid_descriptor_id(query)) {
- log_info(LD_REND, "Got a v2 rendezvous descriptor request for ID '%s'",
- safe_str(escaped(query)));
- switch (rend_cache_lookup_v2_desc_as_dir(query, &descp)) {
- case 1: /* valid */
- write_http_response_header(conn, strlen(descp), NO_METHOD, 0);
- connection_buf_add(descp, strlen(descp), TO_CONN(conn));
- break;
- case 0: /* well-formed but not present */
- write_short_http_response(conn, 404, "Not found");
- break;
- case -1: /* not well-formed */
- write_short_http_response(conn, 400, "Bad request");
- break;
- }
- } else { /* not well-formed */
- write_short_http_response(conn, 400, "Bad request");
- }
- goto done;
- } else {
- /* Not encrypted! */
- write_short_http_response(conn, 404, "Not found");
- }
- done:
- return 0;
-}
-
-/** Helper function for GET `/tor/hs/3/...`. Only for version 3.
+/** Helper function for GET /tor/hs/3/... Only for version 3.
*/
STATIC int
handle_get_hs_descriptor_v3(dir_connection_t *conn,
@@ -1484,7 +1446,7 @@ handle_get_next_bandwidth(dir_connection_t *conn,
compress_method, BANDWIDTH_CACHE_LIFETIME);
if (compress_method != NO_METHOD) {
conn->compress_state = tor_compress_new(1, compress_method,
- choose_compression_level(len/2));
+ choose_compression_level());
log_debug(LD_DIR, "Compressing bandwidth file.");
} else {
log_debug(LD_DIR, "Not compressing bandwidth file.");
@@ -1608,6 +1570,8 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers,
char *url = NULL;
const or_options_t *options = get_options();
+ (void) body_len;
+
log_debug(LD_DIRSERV,"Received POST command.");
conn->base_.state = DIR_CONN_STATE_SERVER_WRITING;
@@ -1626,22 +1590,6 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers,
}
log_debug(LD_DIRSERV,"rewritten url as '%s'.", escaped(url));
- /* Handle v2 rendezvous service publish request. */
- if (connection_dir_is_encrypted(conn) &&
- !strcmpstart(url,"/tor/rendezvous2/publish")) {
- if (rend_cache_store_v2_desc_as_dir(body) < 0) {
- log_warn(LD_REND, "Rejected v2 rend descriptor (body size %d) from %s.",
- (int)body_len,
- connection_describe_peer(TO_CONN(conn)));
- write_short_http_response(conn, 400,
- "Invalid v2 service descriptor rejected");
- } else {
- write_short_http_response(conn, 200, "Service descriptor (v2) stored");
- log_info(LD_REND, "Handled v2 rendezvous descriptor post: accepted");
- }
- goto done;
- }
-
/* Handle HS descriptor publish request. We force an anonymous connection
* (which also tests for encrypted). We do not allow single-hop client to
* post a descriptor onto an HSDir. */
diff --git a/src/feature/dircache/dircache.h b/src/feature/dircache/dircache.h
index d6392e2d42..8e0945125d 100644
--- a/src/feature/dircache/dircache.h
+++ b/src/feature/dircache/dircache.h
@@ -26,7 +26,7 @@ MOCK_DECL(STATIC int, directory_handle_command_post,(dir_connection_t *conn,
STATIC int handle_post_hs_descriptor(const char *url, const char *body);
enum compression_level_t;
-STATIC enum compression_level_t choose_compression_level(ssize_t n_bytes);
+STATIC enum compression_level_t choose_compression_level(void);
struct get_handler_args_t;
STATIC int handle_get_hs_descriptor_v3(dir_connection_t *conn,
diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c
index a5dd856729..30b47232ca 100644
--- a/src/feature/dirclient/dirclient.c
+++ b/src/feature/dirclient/dirclient.c
@@ -738,7 +738,22 @@ connection_dir_client_request_failed(dir_connection_t *conn)
return; /* this was a test fetch. don't retry. */
}
if (!entry_list_is_constrained(get_options()))
- router_set_status(conn->identity_digest, 0); /* don't try this one again */
+ /* We must not set a directory to non-running for HS purposes else we end
+ * up flagging nodes from the hashring has unusable. It doesn't have direct
+ * effect on the HS subsystem because the nodes are selected regardless of
+ * their status but still, we shouldn't flag them as non running.
+ *
+ * One example where this can go bad is if a tor instance gets added a lot
+ * of ephemeral services and with a network with problem then many nodes in
+ * the consenus ends up unusable.
+ *
+ * Furthermore, a service does close any pending directory connections
+ * before uploading a descriptor and thus we can end up here in a natural
+ * way since closing a pending directory connection leads to this code
+ * path. */
+ if (!DIR_PURPOSE_IS_HS(TO_CONN(conn)->purpose)) {
+ router_set_status(conn->identity_digest, 0);
+ }
if (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
log_info(LD_DIR, "Giving up on serverdesc/extrainfo fetch from "
@@ -1944,7 +1959,9 @@ dir_client_decompress_response_body(char **bodyp, size_t *bodylenp,
/* If we're pretty sure that we have a compressed directory, and
* we didn't manage to uncompress it, then warn and bail. */
if (!plausible && !new_body) {
- log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
+ const int LOG_INTERVAL = 3600;
+ static ratelim_t warning_limit = RATELIM_INIT(LOG_INTERVAL);
+ log_fn_ratelim(&warning_limit, LOG_WARN, LD_HTTP,
"Unable to decompress HTTP body (tried %s%s%s, on %s).",
description1,
tried_both?" and ":"",
@@ -2263,18 +2280,23 @@ handle_response_fetch_consensus(dir_connection_t *conn,
if (looks_like_a_consensus_diff(body, body_len)) {
/* First find our previous consensus. Maybe it's in ram, maybe not. */
- cached_dir_t *cd = dirserv_get_consensus(flavname);
+ cached_dir_t *cd = NULL;
const char *consensus_body = NULL;
size_t consensus_body_len;
tor_mmap_t *mapped_consensus = NULL;
- if (cd) {
- consensus_body = cd->dir;
- consensus_body_len = cd->dir_len;
+
+ /* We prefer the mmap'd version over the cached_dir_t version,
+ * since that matches the logic we used when we picked a consensus
+ * back in dir_consensus_request_set_additional_headers. */
+ mapped_consensus = networkstatus_map_cached_consensus(flavname);
+ if (mapped_consensus) {
+ consensus_body = mapped_consensus->data;
+ consensus_body_len = mapped_consensus->size;
} else {
- mapped_consensus = networkstatus_map_cached_consensus(flavname);
- if (mapped_consensus) {
- consensus_body = mapped_consensus->data;
- consensus_body_len = mapped_consensus->size;
+ cd = dirserv_get_consensus(flavname);
+ if (cd) {
+ consensus_body = cd->dir;
+ consensus_body_len = cd->dir_len;
}
}
if (!consensus_body) {
diff --git a/src/feature/dircommon/directory.h b/src/feature/dircommon/directory.h
index 0aa2ff53ef..2cd9c176c8 100644
--- a/src/feature/dircommon/directory.h
+++ b/src/feature/dircommon/directory.h
@@ -87,6 +87,12 @@ const dir_connection_t *CONST_TO_DIR_CONN(const connection_t *c);
(p)==DIR_PURPOSE_UPLOAD_RENDDESC_V2 || \
(p)==DIR_PURPOSE_UPLOAD_HSDESC)
+/** True iff p is a purpose corresponding to onion service that is either
+ * uploading or fetching actions. */
+#define DIR_PURPOSE_IS_HS(p) \
+ ((p) == DIR_PURPOSE_FETCH_HSDESC || \
+ (p) == DIR_PURPOSE_UPLOAD_HSDESC)
+
enum compress_method_t;
int parse_http_response(const char *headers, int *code, time_t *date,
enum compress_method_t *compression, char **response);
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c
index c1334a7d27..9c35936748 100644
--- a/src/feature/hs/hs_cache.c
+++ b/src/feature/hs/hs_cache.c
@@ -353,6 +353,31 @@ static digest256map_t *hs_cache_v3_client;
* objects all related to a specific service. */
static digest256map_t *hs_cache_client_intro_state;
+#define cache_client_desc_free(val) \
+ FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
+
+/** Free memory allocated by <b>desc</b>. */
+static void
+cache_client_desc_free_(hs_cache_client_descriptor_t *desc)
+{
+ if (desc == NULL) {
+ return;
+ }
+ hs_descriptor_free(desc->desc);
+ memwipe(&desc->key, 0, sizeof(desc->key));
+ memwipe(desc->encoded_desc, 0, strlen(desc->encoded_desc));
+ tor_free(desc->encoded_desc);
+ tor_free(desc);
+}
+
+/** Helper function: Use by the free all function to clear the client cache */
+static void
+cache_client_desc_free_void(void *ptr)
+{
+ hs_cache_client_descriptor_t *desc = ptr;
+ cache_client_desc_free(desc);
+}
+
/** Return the size of a client cache entry in bytes. */
static size_t
cache_get_client_entry_size(const hs_cache_client_descriptor_t *entry)
@@ -390,7 +415,18 @@ remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc)
static void
store_v3_desc_as_client(hs_cache_client_descriptor_t *desc)
{
+ hs_cache_client_descriptor_t *cached_desc;
+
tor_assert(desc);
+
+ /* Because the lookup function doesn't return an expired entry, it can linger
+ * in the cache until we clean it up or a new descriptor is stored. So,
+ * before adding, we'll make sure we are not overwriting an old descriptor
+ * (which is OK in terms of semantic) but leads to memory leak. */
+ cached_desc = digest256map_get(hs_cache_v3_client, desc->key.pubkey);
+ if (cached_desc) {
+ cache_client_desc_free(cached_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));
@@ -473,31 +509,6 @@ cache_client_desc_new(const char *desc_str,
return client_desc;
}
-#define cache_client_desc_free(val) \
- FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
-
-/** Free memory allocated by <b>desc</b>. */
-static void
-cache_client_desc_free_(hs_cache_client_descriptor_t *desc)
-{
- if (desc == NULL) {
- return;
- }
- hs_descriptor_free(desc->desc);
- memwipe(&desc->key, 0, sizeof(desc->key));
- memwipe(desc->encoded_desc, 0, strlen(desc->encoded_desc));
- tor_free(desc->encoded_desc);
- tor_free(desc);
-}
-
-/** Helper function: Use by the free all function to clear the client cache */
-static void
-cache_client_desc_free_void(void *ptr)
-{
- hs_cache_client_descriptor_t *desc = ptr;
- cache_client_desc_free(desc);
-}
-
/** Return a newly allocated and initialized hs_cache_intro_state_t object. */
static hs_cache_intro_state_t *
cache_intro_state_new(void)
diff --git a/src/feature/hs/hs_common.h b/src/feature/hs/hs_common.h
index 4a9c7a9918..274017180a 100644
--- a/src/feature/hs/hs_common.h
+++ b/src/feature/hs/hs_common.h
@@ -25,7 +25,7 @@ struct ed25519_keypair_t;
/** 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
diff --git a/src/feature/hs/hs_config.c b/src/feature/hs/hs_config.c
index 7ffc7ecb96..f8d71674de 100644
--- a/src/feature/hs/hs_config.c
+++ b/src/feature/hs/hs_config.c
@@ -179,8 +179,12 @@ static bool
check_value_oob(int i, const char *name, int low, int high)
{
if (i < low || i > high) {
- log_warn(LD_CONFIG, "%s must be between %d and %d, not %d.",
- name, low, high, i);
+ if (low == high) {
+ log_warn(LD_CONFIG, "%s must be %d, not %d.", name, low, i);
+ } else {
+ log_warn(LD_CONFIG, "%s must be between %d and %d, not %d.",
+ name, low, high, i);
+ }
return true;
}
return false;
diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c
index 0656224e48..6e448b322e 100644
--- a/src/feature/hs/hs_descriptor.c
+++ b/src/feature/hs/hs_descriptor.c
@@ -137,7 +137,7 @@ static token_rule_t hs_desc_superencrypted_v3_token_table[] = {
/** Descriptor ruleset for the encrypted section. */
static token_rule_t hs_desc_encrypted_v3_token_table[] = {
T1_START(str_create2_formats, R3_CREATE2_FORMATS, CONCAT_ARGS, NO_OBJ),
- T01(str_intro_auth_required, R3_INTRO_AUTH_REQUIRED, ARGS, NO_OBJ),
+ T01(str_intro_auth_required, R3_INTRO_AUTH_REQUIRED, GE(1), NO_OBJ),
T01(str_single_onion, R3_SINGLE_ONION_SERVICE, ARGS, NO_OBJ),
END_OF_TABLE
};
@@ -2322,6 +2322,7 @@ desc_decode_encrypted_v3(const hs_descriptor_t *desc,
/* Authentication type. It's optional but only once. */
tok = find_opt_by_keyword(tokens, R3_INTRO_AUTH_REQUIRED);
if (tok) {
+ tor_assert(tok->n_args >= 1);
if (!decode_auth_type(desc_encrypted_out, tok->args[0])) {
log_warn(LD_REND, "Service descriptor authentication type has "
"invalid entry(ies).");
diff --git a/src/feature/hs/hs_intropoint.c b/src/feature/hs/hs_intropoint.c
index 69d60f21c3..fa6b54b18a 100644
--- a/src/feature/hs/hs_intropoint.c
+++ b/src/feature/hs/hs_intropoint.c
@@ -514,7 +514,8 @@ hs_intro_received_establish_intro(or_circuit_t *circ, const uint8_t *request,
switch (first_byte) {
case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0:
case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1:
- return rend_mid_establish_intro_legacy(circ, request, request_len);
+ /* Don't accept version 2 introduction anymore. */
+ goto err;
case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519:
return handle_establish_intro(circ, request, request_len);
default:
diff --git a/src/feature/relay/dns.c b/src/feature/relay/dns.c
index 3d9e50524f..71c6f56fb1 100644
--- a/src/feature/relay/dns.c
+++ b/src/feature/relay/dns.c
@@ -211,20 +211,11 @@ evdns_log_cb(int warn, const char *msg)
tor_log(severity, LD_EXIT, "eventdns: %s", msg);
}
-/** Helper: passed to eventdns.c as a callback so it can generate random
- * numbers for transaction IDs and 0x20-hack coding. */
-static void
-dns_randfn_(char *b, size_t n)
-{
- crypto_rand(b,n);
-}
-
/** Initialize the DNS subsystem; called by the OR process. */
int
dns_init(void)
{
init_cache_map();
- evdns_set_random_bytes_fn(dns_randfn_);
if (server_mode(get_options())) {
int r = configure_nameservers(1);
return r;
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index c95f36aa8b..7f156d1150 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -843,6 +843,25 @@ router_initialize_tls_context(void)
(unsigned int)lifetime);
}
+/** Announce URL to bridge status page. */
+STATIC void
+router_announce_bridge_status_page(void)
+{
+ char fingerprint[FINGERPRINT_LEN + 1];
+
+ if (crypto_pk_get_hashed_fingerprint(get_server_identity_key(),
+ fingerprint) < 0) {
+ // LCOV_EXCL_START
+ log_err(LD_GENERAL, "Unable to compute bridge fingerprint");
+ return;
+ // LCOV_EXCL_STOP
+ }
+
+ log_notice(LD_GENERAL, "You can check the status of your bridge relay at "
+ "https://bridges.torproject.org/status?id=%s",
+ fingerprint);
+}
+
/** Compute fingerprint (or hashed fingerprint if hashed is 1) and write
* it to 'fingerprint' (or 'hashed-fingerprint'). Return 0 on success, or
* -1 if Tor should die,
@@ -1145,6 +1164,10 @@ init_keys(void)
return -1;
}
+ /* Display URL to bridge status page. */
+ if (! public_server_mode(options))
+ router_announce_bridge_status_page();
+
if (!authdir_mode(options))
return 0;
/* 6. [authdirserver only] load approved-routers file */
diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h
index aa03c27142..9556a66e68 100644
--- a/src/feature/relay/router.h
+++ b/src/feature/relay/router.h
@@ -129,6 +129,7 @@ void router_free_all(void);
STATIC void get_platform_str(char *platform, size_t len);
STATIC int router_write_fingerprint(int hashed, int ed25519_identity);
STATIC smartlist_t *get_my_declared_family(const or_options_t *options);
+STATIC void router_announce_bridge_status_page(void);
STATIC int load_stats_file(const char *filename, const char *ts_tag,
time_t now, char **out);