diff options
Diffstat (limited to 'src/feature/relay/router.c')
-rw-r--r-- | src/feature/relay/router.c | 138 |
1 files changed, 106 insertions, 32 deletions
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 34d8163c36..b63950ea13 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -44,6 +44,7 @@ #include "feature/relay/selftest.h" #include "lib/geoip/geoip.h" #include "feature/stats/geoip_stats.h" +#include "feature/stats/bwhist.h" #include "feature/stats/rephist.h" #include "lib/crypt_ops/crypto_ed25519.h" #include "lib/crypt_ops/crypto_format.h" @@ -831,30 +832,37 @@ router_initialize_tls_context(void) * -1 if Tor should die, */ STATIC int -router_write_fingerprint(int hashed) +router_write_fingerprint(int hashed, int ed25519_identity) { char *keydir = NULL, *cp = NULL; const char *fname = hashed ? "hashed-fingerprint" : - "fingerprint"; + (ed25519_identity ? "fingerprint-ed25519" : + "fingerprint"); char fingerprint[FINGERPRINT_LEN+1]; const or_options_t *options = get_options(); char *fingerprint_line = NULL; int result = -1; keydir = get_datadir_fname(fname); - log_info(LD_GENERAL,"Dumping %sfingerprint to \"%s\"...", - hashed ? "hashed " : "", keydir); - if (!hashed) { - if (crypto_pk_get_fingerprint(get_server_identity_key(), - fingerprint, 0) < 0) { - log_err(LD_GENERAL,"Error computing fingerprint"); - goto done; - } - } else { - if (crypto_pk_get_hashed_fingerprint(get_server_identity_key(), - fingerprint) < 0) { - log_err(LD_GENERAL,"Error computing hashed fingerprint"); - goto done; + log_info(LD_GENERAL,"Dumping %s%s to \"%s\"...", hashed ? "hashed " : "", + ed25519_identity ? "ed25519 identity" : "fingerprint", keydir); + + if (ed25519_identity) { /* ed25519 identity */ + digest256_to_base64(fingerprint, (const char *) + get_master_identity_key()->pubkey); + } else { /* RSA identity */ + if (!hashed) { + if (crypto_pk_get_fingerprint(get_server_identity_key(), + fingerprint, 0) < 0) { + log_err(LD_GENERAL,"Error computing fingerprint"); + goto done; + } + } else { + if (crypto_pk_get_hashed_fingerprint(get_server_identity_key(), + fingerprint) < 0) { + log_err(LD_GENERAL,"Error computing hashed fingerprint"); + goto done; + } } } @@ -865,15 +873,17 @@ router_write_fingerprint(int hashed) cp = read_file_to_str(keydir, RFTS_IGNORE_MISSING, NULL); if (!cp || strcmp(cp, fingerprint_line)) { if (write_str_to_file(keydir, fingerprint_line, 0)) { - log_err(LD_FS, "Error writing %sfingerprint line to file", - hashed ? "hashed " : ""); + log_err(LD_FS, "Error writing %s%s line to file", + hashed ? "hashed " : "", + ed25519_identity ? "ed25519 identity" : "fingerprint"); goto done; } } - log_notice(LD_GENERAL, "Your Tor %s identity key fingerprint is '%s %s'", - hashed ? "bridge's hashed" : "server's", options->Nickname, - fingerprint); + log_notice(LD_GENERAL, "Your Tor %s identity key %s fingerprint is '%s %s'", + hashed ? "bridge's hashed" : "server's", + ed25519_identity ? "ed25519" : "", + options->Nickname, fingerprint); result = 0; done: @@ -1109,15 +1119,20 @@ init_keys(void) } } - /* 5. Dump fingerprint and possibly hashed fingerprint to files. */ - if (router_write_fingerprint(0)) { + /* 5. Dump fingerprint, ed25519 identity and possibly hashed fingerprint + * to files. */ + if (router_write_fingerprint(0, 0)) { log_err(LD_FS, "Error writing fingerprint to file"); return -1; } - if (!public_server_mode(options) && router_write_fingerprint(1)) { + if (!public_server_mode(options) && router_write_fingerprint(1, 0)) { log_err(LD_FS, "Error writing hashed fingerprint to file"); return -1; } + if (router_write_fingerprint(0, 1)) { + log_err(LD_FS, "Error writing ed25519 identity to file"); + return -1; + } if (!authdir_mode(options)) return 0; @@ -1134,10 +1149,12 @@ init_keys(void) ds = router_get_trusteddirserver_by_digest(digest); if (!ds) { + tor_addr_port_t ipv6_orport; + router_get_advertised_ipv6_or_ap(options, &ipv6_orport); ds = trusted_dir_server_new(options->Nickname, NULL, router_get_advertised_dir_port(options, 0), router_get_advertised_or_port(options), - NULL, + &ipv6_orport, digest, v3_digest, type, 0.0); @@ -1335,6 +1352,17 @@ should_refuse_unknown_exits(const or_options_t *options) } } +/** + * If true, then we will publish our descriptor even if our own IPv4 ORPort + * seems to be unreachable. + **/ +static bool publish_even_when_ipv4_orport_unreachable = false; +/** + * If true, then we will publish our descriptor even if our own IPv6 ORPort + * seems to be unreachable. + **/ +static bool publish_even_when_ipv6_orport_unreachable = false; + /** Decide if we're a publishable server. We are a publishable server if: * - We don't have the ClientOnly option set * and @@ -1363,14 +1391,24 @@ decide_if_publishable_server(void) return 1; if (!router_get_advertised_or_port(options)) return 0; - if (!check_whether_orport_reachable(options)) - return 0; + if (!router_orport_seems_reachable(options, AF_INET)) { + // We have an ipv4 orport, and it doesn't seem reachable. + if (!publish_even_when_ipv4_orport_unreachable) { + return 0; + } + } + if (!router_orport_seems_reachable(options, AF_INET6)) { + // We have an ipv6 orport, and it doesn't seem reachable. + if (!publish_even_when_ipv6_orport_unreachable) { + return 0; + } + } if (router_have_consensus_path() == CONSENSUS_PATH_INTERNAL) { /* All set: there are no exits in the consensus (maybe this is a tiny * test network), so we can't check our DirPort reachability. */ return 1; } else { - return check_whether_dirport_reachable(options); + return router_dirport_seems_reachable(options); } } @@ -1501,7 +1539,22 @@ router_has_advertised_ipv6_orport(const or_options_t *options) return tor_addr_port_is_valid_ap(&ipv6_ap, 0); } -/** Returns true if this router has an advertised IPv6 ORPort. */ +/** Returns true if this router can extend over IPv6. + * + * This check should only be performed by relay extend code. + * + * Clients should check if relays can initiate and accept IPv6 extends using + * node_supports_initiating_ipv6_extends() and + * node_supports_accepting_ipv6_extends(). + * + * As with other extends, relays should assume the client has already + * performed the relevant checks for the next hop. (Otherwise, relays that + * have just added IPv6 ORPorts won't be able to self-test those ORPorts.) + * + * Accepting relays don't need to perform any IPv6-specific checks before + * accepting a connection, because having an IPv6 ORPort implies support for + * the relevant protocol version. + */ MOCK_IMPL(bool, router_can_extend_over_ipv6,(const or_options_t *options)) { @@ -2046,7 +2099,7 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out)) ri->bandwidthburst = relay_get_effective_bwburst(options); /* Report bandwidth, unless we're hibernating or shutting down */ - ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess(); + ri->bandwidthcapacity = hibernating ? 0 : bwhist_bandwidth_assess(); if (dns_seems_to_be_broken() || has_dns_init_failed()) { /* DNS is screwed up; don't claim to be an exit. */ @@ -2373,6 +2426,24 @@ router_rebuild_descriptor(int force) return 0; } +/** Called when we have a new set of consensus parameters. */ +void +router_new_consensus_params(const networkstatus_t *ns) +{ + const int32_t DEFAULT_ASSUME_REACHABLE = 0; + const int32_t DEFAULT_ASSUME_REACHABLE_IPV6 = 0; + int ar, ar6; + ar = networkstatus_get_param(ns, + "assume-reachable", + DEFAULT_ASSUME_REACHABLE, 0, 1); + ar6 = networkstatus_get_param(ns, + "assume-reachable-ipv6", + DEFAULT_ASSUME_REACHABLE_IPV6, 0, 1); + + publish_even_when_ipv4_orport_unreachable = ar; + publish_even_when_ipv6_orport_unreachable = ar || ar6; +} + /** If our router descriptor ever goes this long without being regenerated * because something changed, we force an immediate regenerate-and-upload. */ #define FORCE_REGENERATE_DESCRIPTOR_INTERVAL (18*60*60) @@ -2474,7 +2545,7 @@ check_descriptor_bandwidth_changed(time_t now) /* Consider ourselves to have zero bandwidth if we're hibernating or * shutting down. */ - cur = hibernating ? 0 : rep_hist_bandwidth_assess(); + cur = hibernating ? 0 : bwhist_bandwidth_assess(); if ((prev != cur && (!prev || !cur)) || cur > (prev * BANDWIDTH_CHANGE_FACTOR) || @@ -2525,6 +2596,7 @@ void check_descriptor_ipaddress_changed(time_t now) { uint32_t prev, cur; + tor_addr_t addr; const or_options_t *options = get_options(); const char *method = NULL; char *hostname = NULL; @@ -2537,10 +2609,12 @@ check_descriptor_ipaddress_changed(time_t now) /* XXXX ipv6 */ prev = my_ri->addr; - if (resolve_my_address(LOG_INFO, options, &cur, &method, &hostname) < 0) { + if (!find_my_address(options, AF_INET, LOG_INFO, &addr, &method, + &hostname)) { log_info(LD_CONFIG,"options->Address didn't resolve into an IP."); return; } + cur = tor_addr_to_ipv4h(&addr); if (prev != cur) { char *source; @@ -3135,7 +3209,7 @@ extrainfo_dump_to_string_stats_helper(smartlist_t *chunks, log_info(LD_GENERAL, "Adding stats to extra-info descriptor."); /* Bandwidth usage stats don't have their own option */ { - contents = rep_hist_get_bandwidth_lines(); + contents = bwhist_get_bandwidth_lines(); smartlist_add(chunks, contents); } /* geoip hashes aren't useful unless we are publishing other stats */ |