summaryrefslogtreecommitdiff
path: root/src/feature/relay/router.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/feature/relay/router.c')
-rw-r--r--src/feature/relay/router.c131
1 files changed, 79 insertions, 52 deletions
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index e018561556..47dbcaaad6 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2020, The Tor Project, Inc. */
+ * Copyright (c) 2007-2021, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define ROUTER_PRIVATE
@@ -138,6 +138,18 @@ static authority_cert_t *legacy_key_certificate = NULL;
* used by tor-gencert to sign new signing keys and make new key
* certificates. */
+/** Indicate if the IPv6 address should be omitted from the descriptor when
+ * publishing it. This can happen if the IPv4 is reachable but the
+ * auto-discovered IPv6 is not. We still publish the descriptor.
+ *
+ * Only relays should look at this and only for their descriptor.
+ *
+ * XXX: The real harder fix is to never put in the routerinfo_t a non
+ * reachable address and instead use the last resolved address cache to do
+ * reachability test or anything that has to do with what address tor thinks
+ * it has. */
+static bool omit_ipv6_on_publish = false;
+
/** Return a readonly string with human readable description
* of <b>err</b>.
*/
@@ -831,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,
@@ -1133,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 */
@@ -1322,8 +1357,8 @@ decide_to_advertise_dir_impl(const or_options_t *options,
int
router_should_advertise_dirport(const or_options_t *options, uint16_t dir_port)
{
- /* supports_tunnelled_dir_requests is not relevant, pass 0 */
- return decide_to_advertise_dir_impl(options, dir_port, 0) ? dir_port : 0;
+ /* Only authorities should advertise a DirPort now. */
+ return authdir_mode(options) ? dir_port : 0;
}
/** Front-end to decide_to_advertise_dir_impl(): return 0 if we don't want to
@@ -1396,7 +1431,11 @@ decide_if_publishable_server(void)
return 0;
}
}
- if (!router_orport_seems_reachable(options, AF_INET6)) {
+ /* We could be flagged to omit the IPv6 and if so, don't check for
+ * reachability on the IPv6. This can happen if the address was
+ * auto-discovered but turns out to be non reachable. */
+ if (!omit_ipv6_on_publish &&
+ !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;
@@ -1427,10 +1466,9 @@ consider_publishable_server(int force)
return;
rebuilt = router_rebuild_descriptor(0);
- if (decide_if_publishable_server()) {
+ if (rebuilt && decide_if_publishable_server()) {
set_server_advertised(1);
- if (rebuilt == 0)
- router_upload_dir_desc_to_dirservers(force);
+ router_upload_dir_desc_to_dirservers(force);
} else {
set_server_advertised(0);
}
@@ -1817,7 +1855,7 @@ router_get_my_extrainfo(void)
{
if (!server_mode(get_options()))
return NULL;
- if (router_rebuild_descriptor(0))
+ if (!router_rebuild_descriptor(0))
return NULL;
return desc_extrainfo;
}
@@ -2048,12 +2086,11 @@ MOCK_IMPL(STATIC int,
router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
{
routerinfo_t *ri = NULL;
- tor_addr_t ipv4_addr, ipv6_addr;
+ tor_addr_t ipv4_addr;
char platform[256];
int hibernating = we_are_hibernating();
const or_options_t *options = get_options();
int result = TOR_ROUTERINFO_ERROR_INTERNAL_BUG;
- uint16_t ipv6_orport = 0;
if (BUG(!ri_out)) {
result = TOR_ROUTERINFO_ERROR_INTERNAL_BUG;
@@ -2065,10 +2102,6 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
bool have_v4 = relay_find_addr_to_publish(options, AF_INET,
RELAY_FIND_ADDR_NO_FLAG,
&ipv4_addr);
- bool have_v6 = relay_find_addr_to_publish(options, AF_INET6,
- RELAY_FIND_ADDR_NO_FLAG,
- &ipv6_addr);
-
/* Tor requires a relay to have an IPv4 so bail if we can't find it. */
if (!have_v4) {
log_info(LD_CONFIG, "Don't know my address while generating descriptor. "
@@ -2080,24 +2113,21 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
/* Log a message if the address in the descriptor doesn't match the ORPort
* and DirPort addresses configured by the operator. */
router_check_descriptor_address_consistency(&ipv4_addr);
- router_check_descriptor_address_consistency(&ipv6_addr);
ri = tor_malloc_zero(sizeof(routerinfo_t));
+ tor_addr_copy(&ri->ipv4_addr, &ipv4_addr);
ri->cache_info.routerlist_index = -1;
ri->nickname = tor_strdup(options->Nickname);
/* IPv4. */
- tor_addr_copy(&ri->ipv4_addr, &ipv4_addr);
ri->ipv4_orport = routerconf_find_or_port(options, AF_INET);
ri->ipv4_dirport = routerconf_find_dir_port(options, 0);
- /* IPv6. Do not publish an IPv6 if we don't have an ORPort that can be used
- * with the address. This is possible for instance if the ORPort is
- * IPv4Only. */
- ipv6_orport = routerconf_find_or_port(options, AF_INET6);
- if (have_v6 && ipv6_orport != 0) {
- tor_addr_copy(&ri->ipv6_addr, &ipv6_addr);
- ri->ipv6_orport = ipv6_orport;
+ /* Optionally check for an IPv6. We still publish without one. */
+ if (relay_find_addr_to_publish(options, AF_INET6, RELAY_FIND_ADDR_NO_FLAG,
+ &ri->ipv6_addr)) {
+ ri->ipv6_orport = routerconf_find_or_port(options, AF_INET6);
+ router_check_descriptor_address_consistency(&ri->ipv6_addr);
}
ri->supports_tunnelled_dir_requests =
@@ -2414,9 +2444,10 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild a fresh
* routerinfo, signed server descriptor, and extra-info document for this OR.
- * Return 0 on success, -1 on temporary error.
+ *
+ * Return true on success, else false on temporary error.
*/
-int
+bool
router_rebuild_descriptor(int force)
{
int err = 0;
@@ -2424,13 +2455,13 @@ router_rebuild_descriptor(int force)
extrainfo_t *ei;
if (desc_clean_since && !force)
- return 0;
+ return true;
log_info(LD_OR, "Rebuilding relay descriptor%s", force ? " (forced)" : "");
err = router_build_fresh_descriptor(&ri, &ei);
if (err < 0) {
- return err;
+ return false;
}
routerinfo_free(desc_routerinfo);
@@ -2446,7 +2477,7 @@ router_rebuild_descriptor(int force)
}
desc_dirty_reason = NULL;
control_event_my_descriptor_changed();
- return 0;
+ return true;
}
/** Called when we have a new set of consensus parameters. */
@@ -2467,18 +2498,6 @@ router_new_consensus_params(const networkstatus_t *ns)
publish_even_when_ipv6_orport_unreachable = ar || ar6;
}
-/** Indicate if the IPv6 address should be omitted from the descriptor when
- * publishing it. This can happen if the IPv4 is reachable but the
- * auto-discovered IPv6 is not. We still publish the descriptor.
- *
- * Only relays should look at this and only for their descriptor.
- *
- * XXX: The real harder fix is to never put in the routerinfo_t a non
- * reachable address and instead use the last resolved address cache to do
- * reachability test or anything that has to do with what address tor thinks
- * it has. */
-static bool omit_ipv6_on_publish = false;
-
/** Mark our descriptor out of data iff the IPv6 omit status flag is flipped
* it changes from its previous value.
*
@@ -2679,18 +2698,15 @@ check_descriptor_ipaddress_changed(time_t now)
previous = &my_ri->ipv6_addr;
}
- /* Ignore returned value because we want to notice not only an address
- * change but also if an address is lost (current == UNSPEC). */
- bool found = find_my_address(get_options(), family, LOG_INFO, &current,
- &method, &hostname);
- if (!found) {
- /* Address was possibly not found because it is simply not configured or
- * discoverable. Fallback to our cache, which includes any suggestion
- * sent by a trusted directory server. */
- found = relay_find_addr_to_publish(get_options(), family,
- RELAY_FIND_ADDR_CACHE_ONLY,
- &current);
- }
+ /* Attempt to discovery the publishable address for the family which will
+ * actively attempt to discover the address if we are configured with a
+ * port for the family.
+ *
+ * It is OK to ignore the returned value here since in the failure case,
+ * that is the address was not found, the current value is set to UNSPEC.
+ * Add this (void) so Coverity is happy. */
+ (void) relay_find_addr_to_publish(get_options(), family,
+ RELAY_FIND_ADDR_NO_FLAG, &current);
/* The "current" address might be UNSPEC meaning it was not discovered nor
* found in our current cache. If we had an address before and we have
@@ -3326,6 +3342,11 @@ extrainfo_dump_to_string_stats_helper(smartlist_t *chunks,
"hidserv-stats-end", now, &contents) > 0) {
smartlist_add(chunks, contents);
}
+ if (options->HiddenServiceStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"hidserv-v3-stats",
+ "hidserv-v3-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
if (options->EntryStatistics &&
load_stats_file("stats"PATH_SEPARATOR"entry-stats",
"entry-stats-end", now, &contents) > 0) {
@@ -3351,6 +3372,12 @@ extrainfo_dump_to_string_stats_helper(smartlist_t *chunks,
if (contents)
smartlist_add(chunks, contents);
}
+ if (options->OverloadStatistics) {
+ contents = rep_hist_get_overload_stats_lines();
+ if (contents) {
+ smartlist_add(chunks, contents);
+ }
+ }
/* bridge statistics */
if (should_record_bridge_info(options)) {
const char *bridge_stats = geoip_get_bridge_stats_extrainfo(now);