diff options
author | David Goulet <dgoulet@torproject.org> | 2021-01-11 16:01:22 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2021-01-12 09:46:35 -0500 |
commit | 04b0263974c7ad1327e7a193884cf31d55f7949a (patch) | |
tree | 2645b30b1b01442d6c10e4480cf81a40141d139b /src/feature | |
parent | 6c0f15500b3aa027c90d1c397d4504bb2f4dd41b (diff) | |
download | tor-04b0263974c7ad1327e7a193884cf31d55f7949a.tar.gz tor-04b0263974c7ad1327e7a193884cf31d55f7949a.zip |
hs-v3: Require reasonably live consensus
Some days before this commit, the network experienced a DDoS on the directory
authorities that prevented them to generate a consensus for more than 5 hours
straight.
That in turn entirely disabled onion service v3, client and service side, due
to the subsystem requiring a live consensus to function properly.
We know require a reasonably live consensus which means that the HSv3
subsystem will to its job for using the best consensus tor can find. If the
entire network is using an old consensus, than this should be alright.
If the service happens to use a live consensus while a client is not, it
should still work because the client will use the current SRV it sees which
might be the previous SRV for the service for which it still publish
descriptors for.
If the service is using an old one and somehow can't get a new one while
clients are on a new one, then reachability issues might arise. However, this
is a situation we already have at the moment since the service will simply not
work if it doesn't have a live consensus while a client has one.
Fixes #40237
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/feature')
-rw-r--r-- | src/feature/hs/hs_cache.c | 5 | ||||
-rw-r--r-- | src/feature/hs/hs_client.c | 8 | ||||
-rw-r--r-- | src/feature/hs/hs_common.c | 12 | ||||
-rw-r--r-- | src/feature/hs/hs_service.c | 7 | ||||
-rw-r--r-- | src/feature/hs_common/shared_random_client.c | 23 | ||||
-rw-r--r-- | src/feature/nodelist/nodelist.c | 2 |
6 files changed, 40 insertions, 17 deletions
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c index 05f9940ae6..042ec55fa4 100644 --- a/src/feature/hs/hs_cache.c +++ b/src/feature/hs/hs_cache.c @@ -17,6 +17,7 @@ #include "feature/hs/hs_common.h" #include "feature/hs/hs_client.h" #include "feature/hs/hs_descriptor.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/rend/rendcache.h" @@ -673,7 +674,9 @@ cached_client_descriptor_has_expired(time_t now, /* We use the current consensus time to see if we should expire this * descriptor since we use consensus time for all other parts of the protocol * as well (e.g. to build the blinded key and compute time periods). */ - const networkstatus_t *ns = networkstatus_get_live_consensus(now); + const networkstatus_t *ns = + networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor()); /* If we don't have a recent consensus, consider this entry expired since we * will want to fetch a new HS desc when we get a live consensus. */ if (!ns) { diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index c65f857419..e25919ecb7 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -29,6 +29,7 @@ #include "feature/hs/hs_descriptor.h" #include "feature/hs/hs_ident.h" #include "feature/nodelist/describe.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerset.h" @@ -1181,9 +1182,10 @@ can_client_refetch_desc(const ed25519_public_key_t *identity_pk, goto cannot; } - /* Without a live consensus we can't do any client actions. It is needed to - * compute the hashring for a service. */ - if (!networkstatus_get_live_consensus(approx_time())) { + /* Without a usable consensus we can't do any client actions. It is needed + * to compute the hashring for a service. */ + if (!networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor())) { log_info(LD_REND, "Can't fetch descriptor for service %s because we " "are missing a live consensus. Stalling connection.", safe_str_client(ed25519_fmt(identity_pk))); diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c index ebe49f09a5..de653037d1 100644 --- a/src/feature/hs/hs_common.c +++ b/src/feature/hs/hs_common.c @@ -25,6 +25,7 @@ #include "feature/hs/hs_service.h" #include "feature/hs_common/shared_random_client.h" #include "feature/nodelist/describe.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerset.h" @@ -272,7 +273,9 @@ hs_get_time_period_num(time_t now) if (now != 0) { current_time = now; } else { - networkstatus_t *ns = networkstatus_get_live_consensus(approx_time()); + networkstatus_t *ns = + networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); current_time = ns ? ns->valid_after : approx_time(); } @@ -1098,7 +1101,8 @@ hs_in_period_between_tp_and_srv,(const networkstatus_t *consensus, time_t now)) time_t srv_start_time, tp_start_time; if (!consensus) { - consensus = networkstatus_get_live_consensus(now); + consensus = networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor()); if (!consensus) { return 0; } @@ -1343,7 +1347,9 @@ hs_get_responsible_hsdirs(const ed25519_public_key_t *blinded_pk, sorted_nodes = smartlist_new(); /* Make sure we actually have a live consensus */ - networkstatus_t *c = networkstatus_get_live_consensus(approx_time()); + networkstatus_t *c = + networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); if (!c || smartlist_len(c->routerstatus_list) == 0) { log_warn(LD_REND, "No live consensus so we can't get the responsible " "hidden service directories."); diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index 6d32cae86c..e820ce9d0b 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -23,6 +23,7 @@ #include "feature/hs_common/shared_random_client.h" #include "feature/keymgt/loadkey.h" #include "feature/nodelist/describe.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nickname.h" #include "feature/nodelist/node_select.h" @@ -2500,7 +2501,8 @@ should_rotate_descriptors(hs_service_t *service, time_t now) tor_assert(service); - ns = networkstatus_get_live_consensus(now); + ns = networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor()); if (ns == NULL) { goto no_rotation; } @@ -3100,7 +3102,8 @@ should_service_upload_descriptor(const hs_service_t *service, } /* Don't upload desc if we don't have a live consensus */ - if (!networkstatus_get_live_consensus(now)) { + if (!networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor())) { goto cannot; } diff --git a/src/feature/hs_common/shared_random_client.c b/src/feature/hs_common/shared_random_client.c index 3d6be94080..ead5d681a9 100644 --- a/src/feature/hs_common/shared_random_client.c +++ b/src/feature/hs_common/shared_random_client.c @@ -13,6 +13,7 @@ #include "app/config/config.h" #include "feature/dircommon/voting_schedule.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "lib/encoding/binascii.h" @@ -37,7 +38,9 @@ int get_voting_interval(void) { int interval; - networkstatus_t *consensus = networkstatus_get_live_consensus(time(NULL)); + networkstatus_t *consensus = + networkstatus_get_reasonably_live_consensus(time(NULL), + usable_consensus_flavor()); if (consensus) { interval = (int)(consensus->fresh_until - consensus->valid_after); @@ -142,7 +145,8 @@ sr_get_current(const networkstatus_t *ns) if (ns) { consensus = ns; } else { - consensus = networkstatus_get_live_consensus(approx_time()); + consensus = networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); } /* Ideally we would never be asked for an SRV without a live consensus. Make * sure this assumption is correct. */ @@ -165,7 +169,8 @@ sr_get_previous(const networkstatus_t *ns) if (ns) { consensus = ns; } else { - consensus = networkstatus_get_live_consensus(approx_time()); + consensus = networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); } /* Ideally we would never be asked for an SRV without a live consensus. Make * sure this assumption is correct. */ @@ -237,10 +242,14 @@ sr_state_get_start_time_of_current_protocol_run(void) int voting_interval = get_voting_interval(); time_t beginning_of_curr_round; - /* This function is not used for voting purposes, so if we have a live - consensus, use its valid-after as the beginning of the current round, - otherwise resort to the voting schedule which should always exist. */ - networkstatus_t *ns = networkstatus_get_live_consensus(approx_time()); + /* This function is not used for voting purposes, so if we have a reasonably + * live consensus, use its valid-after as the beginning of the current + * round. If we have no consensus but we're an authority, use our own + * schedule. Otherwise, try using our view of the voting interval to figure + * out when the current round _should_ be starting. */ + networkstatus_t *ns = + networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); if (ns) { beginning_of_curr_round = ns->valid_after; } else { diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index 99d7f746a8..8974d95db6 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -361,7 +361,7 @@ node_set_hsdir_index(node_t *node, const networkstatus_t *ns) tor_assert(node); tor_assert(ns); - if (!networkstatus_is_live(ns, now)) { + if (!networkstatus_consensus_reasonably_live(ns, now)) { static struct ratelim_t live_consensus_ratelim = RATELIM_INIT(30 * 60); log_fn_ratelim(&live_consensus_ratelim, LOG_INFO, LD_GENERAL, "Not setting hsdir index with a non-live consensus."); |