diff options
Diffstat (limited to 'src/feature/relay')
-rw-r--r-- | src/feature/relay/circuitbuild_relay.c | 7 | ||||
-rw-r--r-- | src/feature/relay/dns.c | 10 | ||||
-rw-r--r-- | src/feature/relay/dns.h | 4 | ||||
-rw-r--r-- | src/feature/relay/onion_queue.c | 90 | ||||
-rw-r--r-- | src/feature/relay/relay_config.c | 4 | ||||
-rw-r--r-- | src/feature/relay/relay_metrics.c | 71 | ||||
-rw-r--r-- | src/feature/relay/relay_metrics.h | 6 | ||||
-rw-r--r-- | src/feature/relay/router.c | 60 | ||||
-rw-r--r-- | src/feature/relay/selftest.c | 6 |
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; } |