aboutsummaryrefslogtreecommitdiff
path: root/src/feature/relay
diff options
context:
space:
mode:
Diffstat (limited to 'src/feature/relay')
-rw-r--r--src/feature/relay/circuitbuild_relay.c7
-rw-r--r--src/feature/relay/dns.c10
-rw-r--r--src/feature/relay/dns.h4
-rw-r--r--src/feature/relay/onion_queue.c90
-rw-r--r--src/feature/relay/relay_config.c4
-rw-r--r--src/feature/relay/relay_metrics.c71
-rw-r--r--src/feature/relay/relay_metrics.h6
-rw-r--r--src/feature/relay/router.c60
-rw-r--r--src/feature/relay/selftest.c6
9 files changed, 152 insertions, 106 deletions
diff --git a/src/feature/relay/circuitbuild_relay.c b/src/feature/relay/circuitbuild_relay.c
index ce6cbe6df4..5ece5b4adc 100644
--- a/src/feature/relay/circuitbuild_relay.c
+++ b/src/feature/relay/circuitbuild_relay.c
@@ -389,7 +389,6 @@ circuit_open_connection_for_extend(const struct extend_cell_t *ec,
circ->n_hop = extend_info_new(NULL /*nickname*/,
(const char*)ec->node_id,
&ec->ed_pubkey,
- NULL, /*onion_key*/
NULL, /*curve25519_key*/
&chosen_ap->addr,
chosen_ap->port,
@@ -443,6 +442,12 @@ circuit_extend(struct cell_t *cell, struct circuit_t *circ)
relay_header_unpack(&rh, cell->payload);
+ /* We no longer accept EXTEND messages; only EXTEND2. */
+ if (rh.command == RELAY_COMMAND_EXTEND) {
+ /* TODO: Should we log this? */
+ return -1;
+ }
+
if (extend_cell_parse(&ec, rh.command,
cell->payload+RELAY_HEADER_SIZE,
rh.length) < 0) {
diff --git a/src/feature/relay/dns.c b/src/feature/relay/dns.c
index f6a020d061..eb31678189 100644
--- a/src/feature/relay/dns.c
+++ b/src/feature/relay/dns.c
@@ -563,6 +563,12 @@ send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type,
connection_edge_send_command(conn, RELAY_COMMAND_RESOLVED, buf, buflen);
}
+void
+dns_send_resolved_error_cell(edge_connection_t *conn, uint8_t answer_type)
+{
+ send_resolved_cell(conn, answer_type, NULL);
+}
+
/** Send a response to the RESOLVE request of a connection for an in-addr.arpa
* address on connection <b>conn</b> which yielded the result <b>hostname</b>.
* The answer type will be RESOLVED_HOSTNAME.
@@ -1178,8 +1184,8 @@ dns_found_answer(const char *address, uint8_t query_type,
* resolution.
*
* Do this by sending a RELAY_RESOLVED cell (if the pending stream had sent us
- * RELAY_RESOLVE cell), or by launching an exit connection (if the pending
- * stream had send us a RELAY_BEGIN cell).
+ * a RELAY_RESOLVE cell), or by launching an exit connection (if the pending
+ * stream had sent us a RELAY_BEGIN cell).
*/
static void
inform_pending_connections(cached_resolve_t *resolve)
diff --git a/src/feature/relay/dns.h b/src/feature/relay/dns.h
index 3f8519bd97..5de70039d4 100644
--- a/src/feature/relay/dns.h
+++ b/src/feature/relay/dns.h
@@ -20,6 +20,8 @@ int dns_reset(void);
void connection_dns_remove(edge_connection_t *conn);
void assert_connection_edge_not_dns_pending(edge_connection_t *conn);
int dns_resolve(edge_connection_t *exitconn);
+void dns_send_resolved_error_cell(edge_connection_t *conn,
+ uint8_t answer_type);
int dns_seems_to_be_broken(void);
int dns_seems_to_be_broken_for_ipv6(void);
void dns_reset_correctness_checks(void);
@@ -36,6 +38,8 @@ void dns_launch_correctness_checks(void);
#else /* !defined(HAVE_MODULE_RELAY) */
#define dns_init() (0)
+#define dns_send_resolved_error_cell(conn, answer_type) \
+ ((void)(conn), (void)(answer_type))
#define dns_seems_to_be_broken() (0)
#define has_dns_init_failed() (0)
#define dns_cache_total_allocation() (0)
diff --git a/src/feature/relay/onion_queue.c b/src/feature/relay/onion_queue.c
index f3f4b169f4..9632b51063 100644
--- a/src/feature/relay/onion_queue.c
+++ b/src/feature/relay/onion_queue.c
@@ -50,10 +50,6 @@
#define ONION_QUEUE_MAX_DELAY_MIN 1
#define ONION_QUEUE_MAX_DELAY_MAX INT32_MAX
-#define NUM_NTORS_PER_TAP_DEFAULT 10
-#define NUM_NTORS_PER_TAP_MIN 1
-#define NUM_NTORS_PER_TAP_MAX 100000
-
/** Type for a linked list of circuits that are waiting for a free CPU worker
* to process a waiting onion handshake. */
typedef struct onion_queue_t {
@@ -84,17 +80,9 @@ static int ol_entries[MAX_QUEUE_IDX+1];
static void onion_queue_entry_remove(onion_queue_t *victim);
/** Consensus parameters. */
-static int32_t ns_num_ntors_per_tap = NUM_NTORS_PER_TAP_DEFAULT;
static time_t ns_onion_queue_wait_cutoff = ONION_QUEUE_WAIT_CUTOFF_DEFAULT;
static uint32_t ns_onion_queue_max_delay = ONION_QUEUE_MAX_DELAY_DEFAULT;
-/** Return the number of ntors per tap from the cached parameter. */
-static inline int32_t
-get_num_ntors_per_tap(void)
-{
- return ns_num_ntors_per_tap;
-}
-
/** Return the onion queue wait cutoff value from the cached parameter. */
static inline time_t
get_onion_queue_wait_cutoff(void)
@@ -146,8 +134,12 @@ have_room_for_onionskin(uint16_t type)
const or_options_t *options = get_options();
int num_cpus;
uint64_t max_onion_queue_delay;
- uint64_t tap_usec, ntor_usec;
- uint64_t ntor_during_tap_usec, tap_during_ntor_usec;
+ uint64_t ntor_usec;
+
+ /* We never allow TAP. */
+ if (type == ONION_HANDSHAKE_TYPE_TAP) {
+ return 0;
+ }
/* If we've got fewer than 50 entries, we always have room for one more. */
if (ol_entries[type] < 50)
@@ -164,44 +156,15 @@ have_room_for_onionskin(uint16_t type)
/* Compute how many microseconds we'd expect to need to clear all
* onionskins in various combinations of the queues. */
- /* How long would it take to process all the TAP cells in the queue? */
- tap_usec = estimated_usec_for_onionskins(
- ol_entries[ONION_HANDSHAKE_TYPE_TAP],
- ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
-
/* How long would it take to process all the NTor cells in the queue? */
ntor_usec = estimated_usec_for_onionskins(
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
- /* How long would it take to process the tap cells that we expect to
- * process while draining the ntor queue? */
- tap_during_ntor_usec = estimated_usec_for_onionskins(
- MIN(ol_entries[ONION_HANDSHAKE_TYPE_TAP],
- ol_entries[ONION_HANDSHAKE_TYPE_NTOR] / get_num_ntors_per_tap()),
- ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
-
- /* How long would it take to process the ntor cells that we expect to
- * process while draining the tap queue? */
- ntor_during_tap_usec = estimated_usec_for_onionskins(
- MIN(ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
- ol_entries[ONION_HANDSHAKE_TYPE_TAP] * get_num_ntors_per_tap()),
- ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
-
/* See whether that exceeds MaxOnionQueueDelay. If so, we can't queue
* this. */
if (type == ONION_HANDSHAKE_TYPE_NTOR &&
- (ntor_usec + tap_during_ntor_usec) / 1000 > max_onion_queue_delay)
- return 0;
-
- if (type == ONION_HANDSHAKE_TYPE_TAP &&
- (tap_usec + ntor_during_tap_usec) / 1000 > max_onion_queue_delay)
- return 0;
-
- /* If we support the ntor handshake, then don't let TAP handshakes use
- * more than 2/3 of the space on the queue. */
- if (type == ONION_HANDSHAKE_TYPE_TAP &&
- tap_usec / 1000 > max_onion_queue_delay * 2 / 3)
+ (ntor_usec / 1000) > max_onion_queue_delay)
return 0;
return 1;
@@ -292,38 +255,7 @@ onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
static uint16_t
decide_next_handshake_type(void)
{
- /* The number of times we've chosen ntor lately when both were available. */
- static int recently_chosen_ntors = 0;
-
- if (!ol_entries[ONION_HANDSHAKE_TYPE_NTOR])
- return ONION_HANDSHAKE_TYPE_TAP; /* no ntors? try tap */
-
- if (!ol_entries[ONION_HANDSHAKE_TYPE_TAP]) {
-
- /* Nick wants us to prioritize new tap requests when there aren't
- * any in the queue and we've processed k ntor cells since the last
- * tap cell. This strategy is maybe a good idea, since it starves tap
- * less in the case where tap is rare, or maybe a poor idea, since it
- * makes the new tap cell unfairly jump in front of ntor cells that
- * got here first. In any case this edge case will only become relevant
- * once tap is rare. We should reevaluate whether we like this decision
- * once tap gets more rare. */
- if (ol_entries[ONION_HANDSHAKE_TYPE_NTOR] &&
- recently_chosen_ntors <= get_num_ntors_per_tap())
- ++recently_chosen_ntors;
-
- return ONION_HANDSHAKE_TYPE_NTOR; /* no taps? try ntor */
- }
-
- /* They both have something queued. Pick ntor if we haven't done that
- * too much lately. */
- if (++recently_chosen_ntors <= get_num_ntors_per_tap()) {
- return ONION_HANDSHAKE_TYPE_NTOR;
- }
-
- /* Else, it's time to let tap have its turn. */
- recently_chosen_ntors = 0;
- return ONION_HANDSHAKE_TYPE_TAP;
+ return ONION_HANDSHAKE_TYPE_NTOR;
}
/** Remove the highest priority item from ol_list[] and return it, or
@@ -445,10 +377,4 @@ onion_consensus_has_changed(const networkstatus_t *ns)
ONION_QUEUE_WAIT_CUTOFF_DEFAULT,
ONION_QUEUE_WAIT_CUTOFF_MIN,
ONION_QUEUE_WAIT_CUTOFF_MAX);
-
- ns_num_ntors_per_tap =
- networkstatus_get_param(ns, "NumNTorsPerTAP",
- NUM_NTORS_PER_TAP_DEFAULT,
- NUM_NTORS_PER_TAP_MIN,
- NUM_NTORS_PER_TAP_MAX);
}
diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c
index 0b02461318..320ce8d13a 100644
--- a/src/feature/relay/relay_config.c
+++ b/src/feature/relay/relay_config.c
@@ -1151,8 +1151,8 @@ options_validate_relay_mode(const or_options_t *old_options,
REJECT("BridgeRelay is 1, ORPort is not set. This is an invalid "
"combination.");
- if (options->BridgeRelay == 1 && (options->ExitRelay == 1 ||
- !policy_using_default_exit_options(options))) {
+ if (options->BridgeRelay == 1 && !(options->ExitRelay == 0 ||
+ policy_using_default_exit_options(options))) {
log_warn(LD_CONFIG, "BridgeRelay is 1, but ExitRelay is 1 or an "
"ExitPolicy is configured. Tor will start, but it will not "
"function as an exit relay.");
diff --git a/src/feature/relay/relay_metrics.c b/src/feature/relay/relay_metrics.c
index 8f3b82bd96..492a5945b8 100644
--- a/src/feature/relay/relay_metrics.c
+++ b/src/feature/relay/relay_metrics.c
@@ -13,6 +13,7 @@
#include "core/or/or.h"
#include "core/mainloop/connection.h"
#include "core/mainloop/mainloop.h"
+#include "core/or/command.h"
#include "core/or/congestion_control_common.h"
#include "core/or/congestion_control_vegas.h"
#include "core/or/congestion_control_flow.h"
@@ -54,6 +55,9 @@ static void fill_socket_values(void);
static void fill_onionskins_values(void);
static void fill_oom_values(void);
static void fill_streams_values(void);
+static void fill_relay_circ_proto_violation(void);
+static void fill_relay_destroy_cell(void);
+static void fill_relay_drop_cell(void);
static void fill_relay_flags(void);
static void fill_tcp_exhaustion_values(void);
static void fill_traffic_values(void);
@@ -217,6 +221,27 @@ static const relay_metrics_entry_t base_metrics[] =
.help = "Total number of REND1 cells we received",
.fill_fn = fill_rend1_cells,
},
+ {
+ .key = RELAY_METRICS_CIRC_DESTROY_CELL,
+ .type = METRICS_TYPE_COUNTER,
+ .name = METRICS_NAME(relay_destroy_cell_total),
+ .help = "Total number of DESTROY cell we received",
+ .fill_fn = fill_relay_destroy_cell,
+ },
+ {
+ .key = RELAY_METRICS_CIRC_PROTO_VIOLATION,
+ .type = METRICS_TYPE_COUNTER,
+ .name = METRICS_NAME(relay_circ_proto_violation_total),
+ .help = "Total number of circuit protocol violation",
+ .fill_fn = fill_relay_circ_proto_violation,
+ },
+ {
+ .key = RELAY_METRICS_CIRC_DROP_CELL,
+ .type = METRICS_TYPE_COUNTER,
+ .name = METRICS_NAME(relay_drop_cell_total),
+ .help = "Total number of DROP cell we received",
+ .fill_fn = fill_relay_drop_cell,
+ },
};
static const size_t num_base_metrics = ARRAY_LENGTH(base_metrics);
@@ -433,6 +458,12 @@ fill_dos_values(void)
metrics_store_entry_add_label(sentry,
metrics_format_label("type", "introduce2_rejected"));
metrics_store_entry_update(sentry, hs_dos_get_intro2_rejected_count());
+
+ sentry = metrics_store_add(the_store, rentry->type, rentry->name,
+ rentry->help, 0, NULL);
+ metrics_store_entry_add_label(sentry,
+ metrics_format_label("type", "stream_rejected"));
+ metrics_store_entry_update(sentry, dos_get_num_stream_rejected());
}
/** Fill function for the RELAY_METRICS_CC_COUNTERS metric. */
@@ -1200,6 +1231,46 @@ fill_rend1_cells(void)
}
}
+/** Fill the metrics store for the RELAY_METRICS_CIRC_DESTROY_CELL counter. */
+static void
+fill_relay_destroy_cell(void)
+{
+ metrics_store_entry_t *sentry;
+ const relay_metrics_entry_t *rentry =
+ &base_metrics[RELAY_METRICS_CIRC_DESTROY_CELL];
+
+ sentry = metrics_store_add(the_store, rentry->type, rentry->name,
+ rentry->help, 0, NULL);
+ metrics_store_entry_update(sentry,
+ (int64_t) stats_n_destroy_cells_processed);
+}
+
+/** Fill the metrics store for the RELAY_METRICS_CIRC_DROP_CELL counter. */
+static void
+fill_relay_drop_cell(void)
+{
+ metrics_store_entry_t *sentry;
+ const relay_metrics_entry_t *rentry =
+ &base_metrics[RELAY_METRICS_CIRC_DROP_CELL];
+
+ sentry = metrics_store_add(the_store, rentry->type, rentry->name,
+ rentry->help, 0, NULL);
+ metrics_store_entry_update(sentry, rep_hist_get_drop_cell_received_count());
+}
+
+/** Fill the metrics store for the RELAY_METRICS_CIRC_PROTO_VIOLATION. */
+static void
+fill_relay_circ_proto_violation(void)
+{
+ metrics_store_entry_t *sentry;
+ const relay_metrics_entry_t *rentry =
+ &base_metrics[RELAY_METRICS_CIRC_PROTO_VIOLATION];
+
+ sentry = metrics_store_add(the_store, rentry->type, rentry->name,
+ rentry->help, 0, NULL);
+ metrics_store_entry_update(sentry, circ_n_proto_violation);
+}
+
/** Reset the global store and fill it with all the metrics from base_metrics
* and their associated values.
*
diff --git a/src/feature/relay/relay_metrics.h b/src/feature/relay/relay_metrics.h
index cf9dddf955..e7b5b660fa 100644
--- a/src/feature/relay/relay_metrics.h
+++ b/src/feature/relay/relay_metrics.h
@@ -57,6 +57,12 @@ typedef enum {
RELAY_METRICS_NUM_INTRO1_CELLS,
/** Number of times we received a REND1 cell */
RELAY_METRICS_NUM_REND1_CELLS,
+ /** Number of circuit closed by receiving a DESTROY cell. */
+ RELAY_METRICS_CIRC_DESTROY_CELL,
+ /** Number of circuits closed due to protocol violation. */
+ RELAY_METRICS_CIRC_PROTO_VIOLATION,
+ /** Number of drop cell seen. */
+ RELAY_METRICS_CIRC_DROP_CELL,
} relay_metrics_key_t;
/** The metadata of a relay metric. */
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 1ed9630e09..ab5fe697bc 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -211,8 +211,13 @@ set_onion_key(crypto_pk_t *k)
mark_my_descriptor_dirty("set onion key");
}
-/** Return the current onion key. Requires that the onion key has been
- * loaded or generated. */
+/** Return the current TAP onion key. Requires that the onion key has been
+ * loaded or generated.
+ *
+ * Note that this key is no longer used for anything; we only keep it around
+ * because (as of June 2024) other Tor instances all expect to find it in
+ * our routerdescs.
+ **/
MOCK_IMPL(crypto_pk_t *,
get_onion_key,(void))
{
@@ -220,6 +225,25 @@ get_onion_key,(void))
return onionkey;
}
+/**
+ * Return true iff we should include our TAP onion key in our router
+ * descriptor.
+ */
+static int
+should_publish_tap_onion_key(void)
+{
+#define SHOULD_PUBLISH_TAP_MIN 0
+#define SHOULD_PUBLISH_TAP_MAX 1
+ /* Note that we err on the side of publishing. */
+#define SHOULD_PUBLISH_TAP_DFLT 1
+
+ return networkstatus_get_param(NULL,
+ "publish-dummy-tap-key",
+ SHOULD_PUBLISH_TAP_DFLT,
+ SHOULD_PUBLISH_TAP_MIN,
+ SHOULD_PUBLISH_TAP_MAX);
+}
+
/** Store a full copy of the current onion key into *<b>key</b>, and a full
* copy of the most recent onion key into *<b>last</b>. Store NULL into
* a pointer if the corresponding key does not exist.
@@ -2138,9 +2162,12 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
ri->supports_tunnelled_dir_requests =
directory_permits_begindir_requests(options);
ri->cache_info.published_on = time(NULL);
- /* get_onion_key() must invoke from main thread */
- router_set_rsa_onion_pkey(get_onion_key(), &ri->onion_pkey,
- &ri->onion_pkey_len);
+
+ if (should_publish_tap_onion_key()) {
+ /* get_onion_key() must invoke from main thread */
+ router_set_rsa_onion_pkey(get_onion_key(), &ri->tap_onion_pkey,
+ &ri->tap_onion_pkey_len);
+ }
ri->onion_curve25519_pkey =
tor_memdup(&get_current_curve25519_keypair()->pubkey,
@@ -2777,7 +2804,7 @@ router_dump_router_to_string(routerinfo_t *router,
char published[ISO_TIME_LEN+1];
char fingerprint[FINGERPRINT_LEN+1];
char *extra_info_line = NULL;
- size_t onion_pkeylen, identity_pkeylen;
+ size_t onion_pkeylen=0, identity_pkeylen;
char *family_line = NULL;
char *extra_or_address = NULL;
const or_options_t *options = get_options();
@@ -2835,12 +2862,14 @@ router_dump_router_to_string(routerinfo_t *router,
}
/* PEM-encode the onion key */
- rsa_pubkey = router_get_rsa_onion_pkey(router->onion_pkey,
- router->onion_pkey_len);
- if (crypto_pk_write_public_key_to_string(rsa_pubkey,
- &onion_pkey,&onion_pkeylen)<0) {
- log_warn(LD_BUG,"write onion_pkey to string failed!");
- goto err;
+ rsa_pubkey = router_get_rsa_onion_pkey(router->tap_onion_pkey,
+ router->tap_onion_pkey_len);
+ if (rsa_pubkey) {
+ if (crypto_pk_write_public_key_to_string(rsa_pubkey,
+ &onion_pkey,&onion_pkeylen)<0) {
+ log_warn(LD_BUG,"write onion_pkey to string failed!");
+ goto err;
+ }
}
/* PEM-encode the identity key */
@@ -2851,7 +2880,7 @@ router_dump_router_to_string(routerinfo_t *router,
}
/* Cross-certify with RSA key */
- if (tap_key && router->cache_info.signing_key_cert &&
+ if (tap_key && rsa_pubkey && router->cache_info.signing_key_cert &&
router->cache_info.signing_key_cert->signing_key_included) {
char buf[256];
int tap_cc_len = 0;
@@ -2976,7 +3005,7 @@ router_dump_router_to_string(routerinfo_t *router,
"uptime %ld\n"
"bandwidth %d %d %d\n"
"%s%s"
- "onion-key\n%s"
+ "%s%s"
"signing-key\n%s"
"%s%s"
"%s%s%s",
@@ -2997,7 +3026,8 @@ router_dump_router_to_string(routerinfo_t *router,
extra_info_line ? extra_info_line : "",
(options->DownloadExtraInfo || options->V3AuthoritativeDir) ?
"caches-extra-info\n" : "",
- onion_pkey, identity_pkey,
+ onion_pkey?"onion-key\n":"", onion_pkey?onion_pkey:"",
+ identity_pkey,
rsa_tap_cc_line ? rsa_tap_cc_line : "",
ntor_cc_line ? ntor_cc_line : "",
family_line,
diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c
index 399b6bca6e..0a80a5d47e 100644
--- a/src/feature/relay/selftest.c
+++ b/src/feature/relay/selftest.c
@@ -201,7 +201,6 @@ have_orport_for_family(int family)
static extend_info_t *
extend_info_from_router(const routerinfo_t *r, int family)
{
- crypto_pk_t *rsa_pubkey;
extend_info_t *info;
tor_addr_port_t ap;
@@ -224,15 +223,14 @@ extend_info_from_router(const routerinfo_t *r, int family)
/* We don't have an ORPort for the requested family. */
return NULL;
}
- rsa_pubkey = router_get_rsa_onion_pkey(r->onion_pkey, r->onion_pkey_len);
info = extend_info_new(r->nickname, r->cache_info.identity_digest,
ed_id_key,
- rsa_pubkey, r->onion_curve25519_pkey,
+ r->onion_curve25519_pkey,
&ap.addr, ap.port,
/* TODO-324: Should self-test circuits use
* congestion control? */
NULL, false);
- crypto_pk_free(rsa_pubkey);
+
return info;
}