From 888a0be0b913bea33d9b2ba635b7f27db5fc1b95 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 8 Jan 2020 21:03:20 -0500 Subject: [PATCH 01/12] Define a "dircache" module. For now, this module is enabled whenever the relay module is enabled, and disabled whenever the relay module is disabled. Though they are logically separate, the use cases for running one without the other are rare enough that we don't really want to support compiling them independently. --- configure.ac | 10 +++++++++- doc/HACKING/Module.md | 12 +++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 894ca2b0f8..85ffc1c752 100644 --- a/configure.ac +++ b/configure.ac @@ -278,7 +278,7 @@ dnl Tor modules options. These options are namespaced with --disable-module-XXX dnl --- dnl All our modules. -m4_define(MODULES, relay dirauth) +m4_define(MODULES, relay dirauth dircache) dnl Relay module. AC_ARG_ENABLE([module-relay], @@ -289,6 +289,14 @@ AM_COND_IF(BUILD_MODULE_RELAY, AC_DEFINE([HAVE_MODULE_RELAY], [1], [Compile with Relay feature support])) +dnl Dircache module. (This cannot be enabled or disabled independently of +dnl the relay module.) +AM_CONDITIONAL(BUILD_MODULE_DIRCACHE, + [test "x$enable_module_relay" != "xno"]) +AM_COND_IF(BUILD_MODULE_DIRCACHE, + AC_DEFINE([HAVE_MODULE_DIRCACHE], [1], + [Compile with directory cache support])) + dnl Directory Authority module. AC_ARG_ENABLE([module-dirauth], AS_HELP_STRING([--disable-module-dirauth], diff --git a/doc/HACKING/Module.md b/doc/HACKING/Module.md index 3a07d0c639..781bb978f2 100644 --- a/doc/HACKING/Module.md +++ b/doc/HACKING/Module.md @@ -11,12 +11,18 @@ selectively enable or disable, at `configure` time. Currently, tor has these modules: - Relay subsystem (relay) + - Directory cache system (dircache). - Directory Authority subsystem (dirauth) -dirauth is located in its own directory in `src/feature/dirauth/`. +The dirauth code is located in its own directory in `src/feature/dirauth/`. -Relay is located in directories named `src/*/*relay` and `src/*/*dircache`, -which are being progressively refactored and disabled. +The relay code is located in a directory named `src/*/*relay`, which is +being progressively refactored and disabled. + +The dircache code is located in `src/*/*dircache`. Right now, it is +disabled if and only if the relay module is disabled. (We are treating +them as separate modules because they are logically independent, not +because you would actually want to run one without the other.) To disable a module, pass `--disable-module-{dirauth,relay}` at configure time. All modules are currently enabled by default. From 4cf15ee015b8e4228a8d817cb54067853bf38378 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 8 Jan 2020 21:24:26 -0500 Subject: [PATCH 02/12] Move dir_split_resource_into_spoolable() to dircache module. Only directory caches actually need to spool things. --- src/feature/dircache/dirserv.c | 31 +++++++++++++++++++++++++++++++ src/feature/dircache/dirserv.h | 7 +++++++ src/feature/dircommon/directory.c | 31 ------------------------------- src/feature/dircommon/directory.h | 6 ------ 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/feature/dircache/dirserv.c b/src/feature/dircache/dirserv.c index 5d38d1b8aa..738b1928a3 100644 --- a/src/feature/dircache/dirserv.c +++ b/src/feature/dircache/dirserv.c @@ -266,6 +266,37 @@ dirserv_get_consensus,(const char *flavor_name)) return strmap_get(cached_consensuses, flavor_name); } +/** As dir_split_resource_into_fingerprints, but instead fills + * spool_out with a list of spoolable_resource_t for the resource + * identified through source. */ +int +dir_split_resource_into_spoolable(const char *resource, + dir_spool_source_t source, + smartlist_t *spool_out, + int *compressed_out, + int flags) +{ + smartlist_t *fingerprints = smartlist_new(); + + tor_assert(flags & (DSR_HEX|DSR_BASE64)); + const size_t digest_len = + (flags & DSR_DIGEST256) ? DIGEST256_LEN : DIGEST_LEN; + + int r = dir_split_resource_into_fingerprints(resource, fingerprints, + compressed_out, flags); + /* This is not a very efficient implementation XXXX */ + SMARTLIST_FOREACH_BEGIN(fingerprints, uint8_t *, digest) { + spooled_resource_t *spooled = + spooled_resource_new(source, digest, digest_len); + if (spooled) + smartlist_add(spool_out, spooled); + tor_free(digest); + } SMARTLIST_FOREACH_END(digest); + + smartlist_free(fingerprints); + return r; +} + /** As dirserv_get_routerdescs(), but instead of getting signed_descriptor_t * pointers, adds copies of digests to fps_out, and doesn't use the * /tor/server/ prefix. For a /d/ request, adds descriptor digests; for other diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h index cec17121e6..a4e10dd166 100644 --- a/src/feature/dircache/dirserv.h +++ b/src/feature/dircache/dirserv.h @@ -73,6 +73,13 @@ typedef struct spooled_resource_t { int connection_dirserv_flushed_some(dir_connection_t *conn); +enum dir_spool_source_t; +int dir_split_resource_into_spoolable(const char *resource, + enum dir_spool_source_t source, + smartlist_t *spool_out, + int *compressed_out, + int flags); + int directory_fetches_from_authorities(const or_options_t *options); int directory_fetches_dir_info_early(const or_options_t *options); int directory_fetches_dir_info_later(const or_options_t *options); diff --git a/src/feature/dircommon/directory.c b/src/feature/dircommon/directory.c index f65d3eec0c..b177fe5201 100644 --- a/src/feature/dircommon/directory.c +++ b/src/feature/dircommon/directory.c @@ -702,34 +702,3 @@ dir_split_resource_into_fingerprints(const char *resource, smartlist_free(fp_tmp); return 0; } - -/** As dir_split_resource_into_fingerprints, but instead fills - * spool_out with a list of spoolable_resource_t for the resource - * identified through source. */ -int -dir_split_resource_into_spoolable(const char *resource, - dir_spool_source_t source, - smartlist_t *spool_out, - int *compressed_out, - int flags) -{ - smartlist_t *fingerprints = smartlist_new(); - - tor_assert(flags & (DSR_HEX|DSR_BASE64)); - const size_t digest_len = - (flags & DSR_DIGEST256) ? DIGEST256_LEN : DIGEST_LEN; - - int r = dir_split_resource_into_fingerprints(resource, fingerprints, - compressed_out, flags); - /* This is not a very efficient implementation XXXX */ - SMARTLIST_FOREACH_BEGIN(fingerprints, uint8_t *, digest) { - spooled_resource_t *spooled = - spooled_resource_new(source, digest, digest_len); - if (spooled) - smartlist_add(spool_out, spooled); - tor_free(digest); - } SMARTLIST_FOREACH_END(digest); - - smartlist_free(fingerprints); - return r; -} diff --git a/src/feature/dircommon/directory.h b/src/feature/dircommon/directory.h index 1ed2138d08..0f26cdeff9 100644 --- a/src/feature/dircommon/directory.h +++ b/src/feature/dircommon/directory.h @@ -108,12 +108,6 @@ void connection_dir_about_to_close(dir_connection_t *dir_conn); int dir_split_resource_into_fingerprints(const char *resource, smartlist_t *fp_out, int *compressed_out, int flags); -enum dir_spool_source_t; -int dir_split_resource_into_spoolable(const char *resource, - enum dir_spool_source_t source, - smartlist_t *spool_out, - int *compressed_out, - int flags); int dir_split_resource_into_fingerprint_pairs(const char *res, smartlist_t *pairs_out); char *directory_dump_request_log(void); From fe8156dbc20870bb2e065aa10ca7f2e993958597 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 8 Jan 2020 21:32:16 -0500 Subject: [PATCH 03/12] Move dirserv_get_routerdescs() to control_getinfo.c This function had some XXX comments indicating (correctly) that it was not actually used by the dirserver code, and that only the controller still used it. --- src/feature/control/control_getinfo.c | 83 ++++++++++++++++++++++++++- src/feature/dircache/dirserv.c | 81 -------------------------- src/feature/dircache/dirserv.h | 2 - 3 files changed, 82 insertions(+), 84 deletions(-) diff --git a/src/feature/control/control_getinfo.c b/src/feature/control/control_getinfo.c index 48c1854941..6f30878d23 100644 --- a/src/feature/control/control_getinfo.c +++ b/src/feature/control/control_getinfo.c @@ -34,6 +34,7 @@ #include "feature/dircache/dirserv.h" #include "feature/dirclient/dirclient.h" #include "feature/dirclient/dlstatus.h" +#include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" #include "feature/hs/hs_cache.h" #include "feature/hs_common/shared_random_client.h" @@ -361,6 +362,86 @@ getinfo_helper_current_consensus(consensus_flavor_t flavor, return 0; } +/** Helper for getinfo_helper_dir. + * + * Add a signed_descriptor_t to descs_out for each router matching + * key. The key should be either + * - "/tor/server/authority" for our own routerinfo; + * - "/tor/server/all" for all the routerinfos we have, concatenated; + * - "/tor/server/fp/FP" where FP is a plus-separated sequence of + * hex identity digests; or + * - "/tor/server/d/D" where D is a plus-separated sequence + * of server descriptor digests, in hex. + * + * Return 0 if we found some matching descriptors, or -1 if we do not + * have any descriptors, no matching descriptors, or if we did not + * recognize the key (URL). + * If -1 is returned *msg will be set to an appropriate error + * message. + */ +static int +controller_get_routerdescs(smartlist_t *descs_out, const char *key, + const char **msg) +{ + *msg = NULL; + + if (!strcmp(key, "/tor/server/all")) { + routerlist_t *rl = router_get_routerlist(); + SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r, + smartlist_add(descs_out, &(r->cache_info))); + } else if (!strcmp(key, "/tor/server/authority")) { + const routerinfo_t *ri = router_get_my_routerinfo(); + if (ri) + smartlist_add(descs_out, (void*) &(ri->cache_info)); + } else if (!strcmpstart(key, "/tor/server/d/")) { + smartlist_t *digests = smartlist_new(); + key += strlen("/tor/server/d/"); + dir_split_resource_into_fingerprints(key, digests, NULL, + DSR_HEX|DSR_SORT_UNIQ); + SMARTLIST_FOREACH(digests, const char *, d, + { + signed_descriptor_t *sd = router_get_by_descriptor_digest(d); + if (sd) + smartlist_add(descs_out,sd); + }); + SMARTLIST_FOREACH(digests, char *, d, tor_free(d)); + smartlist_free(digests); + } else if (!strcmpstart(key, "/tor/server/fp/")) { + smartlist_t *digests = smartlist_new(); + time_t cutoff = time(NULL) - ROUTER_MAX_AGE_TO_PUBLISH; + key += strlen("/tor/server/fp/"); + dir_split_resource_into_fingerprints(key, digests, NULL, + DSR_HEX|DSR_SORT_UNIQ); + SMARTLIST_FOREACH_BEGIN(digests, const char *, d) { + if (router_digest_is_me(d)) { + /* calling router_get_my_routerinfo() to make sure it exists */ + const routerinfo_t *ri = router_get_my_routerinfo(); + if (ri) + smartlist_add(descs_out, (void*) &(ri->cache_info)); + } else { + const routerinfo_t *ri = router_get_by_id_digest(d); + /* Don't actually serve a descriptor that everyone will think is + * expired. This is an (ugly) workaround to keep buggy 0.1.1.10 + * Tors from downloading descriptors that they will throw away. + */ + if (ri && ri->cache_info.published_on > cutoff) + smartlist_add(descs_out, (void*) &(ri->cache_info)); + } + } SMARTLIST_FOREACH_END(d); + SMARTLIST_FOREACH(digests, char *, d, tor_free(d)); + smartlist_free(digests); + } else { + *msg = "Key not recognized"; + return -1; + } + + if (!smartlist_len(descs_out)) { + *msg = "Servers unavailable"; + return -1; + } + return 0; +} + /** Implementation helper for GETINFO: knows the answers for questions about * directory information. */ STATIC int @@ -590,7 +671,7 @@ getinfo_helper_dir(control_connection_t *control_conn, int res; char *cp; tor_asprintf(&url, "/tor/%s", question+4); - res = dirserv_get_routerdescs(descs, url, &msg); + res = controller_get_routerdescs(descs, url, &msg); if (res) { log_warn(LD_CONTROL, "getinfo '%s': %s", question, msg); smartlist_free(descs); diff --git a/src/feature/dircache/dirserv.c b/src/feature/dircache/dirserv.c index 738b1928a3..7212614791 100644 --- a/src/feature/dircache/dirserv.c +++ b/src/feature/dircache/dirserv.c @@ -363,87 +363,6 @@ dirserv_get_routerdesc_spool(smartlist_t *spool_out, return 0; } -/** Add a signed_descriptor_t to descs_out for each router matching - * key. The key should be either - * - "/tor/server/authority" for our own routerinfo; - * - "/tor/server/all" for all the routerinfos we have, concatenated; - * - "/tor/server/fp/FP" where FP is a plus-separated sequence of - * hex identity digests; or - * - "/tor/server/d/D" where D is a plus-separated sequence - * of server descriptor digests, in hex. - * - * Return 0 if we found some matching descriptors, or -1 if we do not - * have any descriptors, no matching descriptors, or if we did not - * recognize the key (URL). - * If -1 is returned *msg will be set to an appropriate error - * message. - * - * XXXX rename this function. It's only called from the controller. - * XXXX in fact, refactor this function, merging as much as possible. - */ -int -dirserv_get_routerdescs(smartlist_t *descs_out, const char *key, - const char **msg) -{ - *msg = NULL; - - if (!strcmp(key, "/tor/server/all")) { - routerlist_t *rl = router_get_routerlist(); - SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r, - smartlist_add(descs_out, &(r->cache_info))); - } else if (!strcmp(key, "/tor/server/authority")) { - const routerinfo_t *ri = router_get_my_routerinfo(); - if (ri) - smartlist_add(descs_out, (void*) &(ri->cache_info)); - } else if (!strcmpstart(key, "/tor/server/d/")) { - smartlist_t *digests = smartlist_new(); - key += strlen("/tor/server/d/"); - dir_split_resource_into_fingerprints(key, digests, NULL, - DSR_HEX|DSR_SORT_UNIQ); - SMARTLIST_FOREACH(digests, const char *, d, - { - signed_descriptor_t *sd = router_get_by_descriptor_digest(d); - if (sd) - smartlist_add(descs_out,sd); - }); - SMARTLIST_FOREACH(digests, char *, d, tor_free(d)); - smartlist_free(digests); - } else if (!strcmpstart(key, "/tor/server/fp/")) { - smartlist_t *digests = smartlist_new(); - time_t cutoff = time(NULL) - ROUTER_MAX_AGE_TO_PUBLISH; - key += strlen("/tor/server/fp/"); - dir_split_resource_into_fingerprints(key, digests, NULL, - DSR_HEX|DSR_SORT_UNIQ); - SMARTLIST_FOREACH_BEGIN(digests, const char *, d) { - if (router_digest_is_me(d)) { - /* calling router_get_my_routerinfo() to make sure it exists */ - const routerinfo_t *ri = router_get_my_routerinfo(); - if (ri) - smartlist_add(descs_out, (void*) &(ri->cache_info)); - } else { - const routerinfo_t *ri = router_get_by_id_digest(d); - /* Don't actually serve a descriptor that everyone will think is - * expired. This is an (ugly) workaround to keep buggy 0.1.1.10 - * Tors from downloading descriptors that they will throw away. - */ - if (ri && ri->cache_info.published_on > cutoff) - smartlist_add(descs_out, (void*) &(ri->cache_info)); - } - } SMARTLIST_FOREACH_END(d); - SMARTLIST_FOREACH(digests, char *, d, tor_free(d)); - smartlist_free(digests); - } else { - *msg = "Key not recognized"; - return -1; - } - - if (!smartlist_len(descs_out)) { - *msg = "Servers unavailable"; - return -1; - } - return 0; -} - /* ========== * Spooling code. * ========== */ diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h index a4e10dd166..895cef9484 100644 --- a/src/feature/dircache/dirserv.h +++ b/src/feature/dircache/dirserv.h @@ -101,8 +101,6 @@ int dirserv_get_routerdesc_spool(smartlist_t *spools_out, const char *key, dir_spool_source_t source, int conn_is_encrypted, const char **msg_out); -int dirserv_get_routerdescs(smartlist_t *descs_out, const char *key, - const char **msg); void dirserv_free_all(void); void cached_dir_decref(cached_dir_t *d); From 6e12a8f04714aa56308b06c691066cc3d4b0090b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 8 Jan 2020 21:43:02 -0500 Subject: [PATCH 04/12] Use dir_conn_clear_spool() in connection.c. This is cleaner than iterating over the spool. --- src/core/mainloop/connection.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 09b75c4e5a..f0ebce9bbb 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -719,11 +719,7 @@ connection_free_minimal(connection_t *conn) tor_free(dir_conn->requested_resource); tor_compress_free(dir_conn->compress_state); - if (dir_conn->spool) { - SMARTLIST_FOREACH(dir_conn->spool, spooled_resource_t *, spooled, - spooled_resource_free(spooled)); - smartlist_free(dir_conn->spool); - } + dir_conn_clear_spool(dir_conn); rend_data_free(dir_conn->rend_data); hs_ident_dir_conn_free(dir_conn->hs_ident); From 8a0c739467c87c6d7358d112bd1400250ad6e5c4 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 8 Jan 2020 21:13:29 -0500 Subject: [PATCH 05/12] Disable feature/dircache files when dircache module is disabled. To make Tor still work, we define a minimal dircache_stub.c file that defines the entry points to the module that can actually be seen by the compiler when we're building with dircache and relay disabled. --- src/core/include.am | 18 +++- src/feature/dircache/dircache_stub.c | 152 +++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 src/feature/dircache/dircache_stub.c diff --git a/src/core/include.am b/src/core/include.am index bd36d01f21..1861f6cd41 100644 --- a/src/core/include.am +++ b/src/core/include.am @@ -91,10 +91,6 @@ LIBTOR_APP_A_SOURCES = \ src/feature/control/control_proto.c \ src/feature/control/fmt_serverstatus.c \ src/feature/control/getinfo_geoip.c \ - src/feature/dircache/conscache.c \ - src/feature/dircache/consdiffmgr.c \ - src/feature/dircache/dircache.c \ - src/feature/dircache/dirserv.c \ src/feature/dirclient/dirclient.c \ src/feature/dirclient/dlstatus.c \ src/feature/dircommon/consdiff.c \ @@ -183,6 +179,13 @@ MODULE_RELAY_SOURCES = \ src/feature/relay/relay_sys.c \ src/feature/relay/transport_config.c +# The Directory Cache module. +MODULE_DIRCACHE_SOURCES = \ + src/feature/dircache/conscache.c \ + src/feature/dircache/consdiffmgr.c \ + src/feature/dircache/dircache.c \ + src/feature/dircache/dirserv.c + # The Directory Authority module. MODULE_DIRAUTH_SOURCES = \ src/feature/dirauth/authmode.c \ @@ -209,6 +212,12 @@ else LIBTOR_APP_A_STUB_SOURCES += src/feature/relay/relay_stub.c endif +if BUILD_MODULE_DIRCACHE +LIBTOR_APP_A_SOURCES += $(MODULE_DIRCACHE_SOURCES) +else +LIBTOR_APP_A_STUB_SOURCES += src/feature/dircache/dircache_stub.c +endif + if BUILD_MODULE_DIRAUTH LIBTOR_APP_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) else @@ -222,6 +231,7 @@ if UNITTESTS_ENABLED # Add the sources of the modules that are needed for tests to work here. LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_RELAY_SOURCES) +LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_DIRCACHE_SOURCES) LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) src_core_libtor_app_testing_a_SOURCES = $(LIBTOR_APP_TESTING_A_SOURCES) diff --git a/src/feature/dircache/dircache_stub.c b/src/feature/dircache/dircache_stub.c new file mode 100644 index 0000000000..dcab3bbbb9 --- /dev/null +++ b/src/feature/dircache/dircache_stub.c @@ -0,0 +1,152 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file dircache_stub.c + * @brief Stub declarations for use when dircache module is disabled. + **/ + +#include "core/or/or.h" +#include "feature/dircache/consdiffmgr.h" +#include "feature/dircache/dircache.h" +#include "feature/dircache/dirserv.h" +#include "feature/dircommon/dir_connection_st.h" + +int +directory_handle_command(dir_connection_t *conn) +{ + (void) conn; + tor_assert_nonfatal_unreached_once(); + return -1; +} + +int +connection_dirserv_flushed_some(dir_connection_t *conn) +{ + (void) conn; + tor_assert_nonfatal_unreached_once(); + return -1; +} + +int +directory_fetches_from_authorities(const or_options_t *options) +{ + (void) options; + return 0; +} + +int +directory_fetches_dir_info_early(const or_options_t *options) +{ + (void) options; + return 0; +} + +int +directory_fetches_dir_info_later(const or_options_t *options) +{ + (void) options; + return 0; +} + +int +directory_caches_unknown_auth_certs(const or_options_t *options) +{ + (void) options; + return 0; +} + +int +directory_caches_dir_info(const or_options_t *options) +{ + (void) options; + return 0; +} + +int +directory_permits_begindir_requests(const or_options_t *options) +{ + (void) options; + return 0; +} + +int +directory_too_idle_to_fetch_descriptors(const or_options_t *options, + time_t now) +{ + (void)options; + (void)now; + return 0; +} + +cached_dir_t * +dirserv_get_consensus(const char *flavor_name) +{ + (void) flavor_name; + return NULL; +} + +void +dir_conn_clear_spool(dir_connection_t *conn) +{ + if (!conn) + return; + tor_assert_nonfatal_once(conn->spool == NULL); +} + +void +consdiffmgr_enable_background_compression(void) +{ +} + +void +dirserv_set_cached_consensus_networkstatus(const char *networkstatus, + size_t networkstatus_len, + const char *flavor_name, + const common_digests_t *digests, + const uint8_t *sha3_as_signed, + time_t published) +{ + (void)networkstatus; + (void)networkstatus_len; + (void)flavor_name; + (void)digests; + (void)sha3_as_signed; + (void)published; +} + +int +consdiffmgr_add_consensus(const char *consensus, + size_t consensus_len, + const networkstatus_t *as_parsed) +{ + (void)consensus; + (void)consensus_len; + (void)as_parsed; + return 0; +} + +int +consdiffmgr_register_with_sandbox(struct sandbox_cfg_elem_t **cfg) +{ + (void)cfg; + return 0; +} + +int +consdiffmgr_cleanup(void) +{ + return 0; +} + +void +consdiffmgr_free_all(void) +{ +} + +void +dirserv_free_all(void) +{ +} From a1bc471dd477864105cc13e8ab69ebd05619ea9b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 8 Jan 2020 21:55:41 -0500 Subject: [PATCH 06/12] Add a changes file for disabling the dircache code. --- changes/feature32487 | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changes/feature32487 diff --git a/changes/feature32487 b/changes/feature32487 new file mode 100644 index 0000000000..520ad8db41 --- /dev/null +++ b/changes/feature32487 @@ -0,0 +1,3 @@ + o Minor features (disabling relay support): + - When Tor is compiled --disable-module-relay, we also omit the + code used to act as a directory cache. Closes ticket 32487. From 773bcf56290674cdc157f6e39894d31b366f8c50 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 15 Jan 2020 11:43:14 -0500 Subject: [PATCH 07/12] Move dirclient-related functions out of dirserv, and reenable them I had incorrectly identified these functions as dircache-only, when in fact they apply to everyone who acts a directory client. --- src/app/config/config.c | 2 +- src/core/include.am | 2 + src/core/mainloop/mainloop.c | 2 +- src/feature/dircache/dircache_stub.c | 30 --------- src/feature/dircache/dirserv.c | 63 +----------------- src/feature/dircache/dirserv.h | 5 -- src/feature/dirclient/dirclient.c | 1 + src/feature/dirclient/dirclient_modes.c | 85 +++++++++++++++++++++++++ src/feature/dirclient/dirclient_modes.h | 23 +++++++ src/feature/nodelist/microdesc.c | 1 + src/feature/nodelist/networkstatus.c | 1 + src/feature/nodelist/nodelist.c | 2 +- src/feature/nodelist/routerlist.c | 1 + src/test/test_config.c | 1 + 14 files changed, 119 insertions(+), 100 deletions(-) create mode 100644 src/feature/dirclient/dirclient_modes.c create mode 100644 src/feature/dirclient/dirclient_modes.h diff --git a/src/app/config/config.c b/src/app/config/config.c index d197e2b0cc..f9bfb05125 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -88,7 +88,7 @@ #include "feature/control/control.h" #include "feature/control/control_auth.h" #include "feature/control/control_events.h" -#include "feature/dircache/dirserv.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/hibernate/hibernate.h" #include "feature/hs/hs_config.h" #include "feature/nodelist/dirlist.h" diff --git a/src/core/include.am b/src/core/include.am index 1861f6cd41..f332b3758b 100644 --- a/src/core/include.am +++ b/src/core/include.am @@ -92,6 +92,7 @@ LIBTOR_APP_A_SOURCES = \ src/feature/control/fmt_serverstatus.c \ src/feature/control/getinfo_geoip.c \ src/feature/dirclient/dirclient.c \ + src/feature/dirclient/dirclient_modes.c \ src/feature/dirclient/dlstatus.c \ src/feature/dircommon/consdiff.c \ src/feature/dircommon/directory.c \ @@ -391,6 +392,7 @@ noinst_HEADERS += \ src/feature/dircache/dirserv.h \ src/feature/dirclient/dir_server_st.h \ src/feature/dirclient/dirclient.h \ + src/feature/dirclient/dirclient_modes.h \ src/feature/dirclient/dlstatus.h \ src/feature/dirclient/download_status_st.h \ src/feature/dircommon/consdiff.h \ diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index aac60dcd90..230bf4a25f 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -77,7 +77,7 @@ #include "feature/control/control_events.h" #include "feature/dirauth/authmode.h" #include "feature/dircache/consdiffmgr.h" -#include "feature/dircache/dirserv.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" #include "feature/hs/hs_cache.h" diff --git a/src/feature/dircache/dircache_stub.c b/src/feature/dircache/dircache_stub.c index dcab3bbbb9..f6804dad76 100644 --- a/src/feature/dircache/dircache_stub.c +++ b/src/feature/dircache/dircache_stub.c @@ -30,27 +30,6 @@ connection_dirserv_flushed_some(dir_connection_t *conn) return -1; } -int -directory_fetches_from_authorities(const or_options_t *options) -{ - (void) options; - return 0; -} - -int -directory_fetches_dir_info_early(const or_options_t *options) -{ - (void) options; - return 0; -} - -int -directory_fetches_dir_info_later(const or_options_t *options) -{ - (void) options; - return 0; -} - int directory_caches_unknown_auth_certs(const or_options_t *options) { @@ -72,15 +51,6 @@ directory_permits_begindir_requests(const or_options_t *options) return 0; } -int -directory_too_idle_to_fetch_descriptors(const or_options_t *options, - time_t now) -{ - (void)options; - (void)now; - return 0; -} - cached_dir_t * dirserv_get_consensus(const char *flavor_name) { diff --git a/src/feature/dircache/dirserv.c b/src/feature/dircache/dirserv.c index 7212614791..fb8db879a4 100644 --- a/src/feature/dircache/dirserv.c +++ b/src/feature/dircache/dirserv.c @@ -68,55 +68,7 @@ static cached_dir_t *lookup_cached_dir_by_fp(const uint8_t *fp); /********************************************************************/ /* A set of functions to answer questions about how we'd like to behave - * as a directory mirror/client. */ - -/** Return 1 if we fetch our directory material directly from the - * authorities, rather than from a mirror. */ -int -directory_fetches_from_authorities(const or_options_t *options) -{ - const routerinfo_t *me; - uint32_t addr; - int refuseunknown; - if (options->FetchDirInfoEarly) - return 1; - if (options->BridgeRelay == 1) - return 0; - if (server_mode(options) && - router_pick_published_address(options, &addr, 1) < 0) - return 1; /* we don't know our IP address; ask an authority. */ - refuseunknown = ! router_my_exit_policy_is_reject_star() && - should_refuse_unknown_exits(options); - if (!dir_server_mode(options) && !refuseunknown) - return 0; - if (!server_mode(options) || !advertised_server_mode()) - return 0; - me = router_get_my_routerinfo(); - if (!me || (!me->supports_tunnelled_dir_requests && !refuseunknown)) - return 0; /* if we don't service directory requests, return 0 too */ - return 1; -} - -/** Return 1 if we should fetch new networkstatuses, descriptors, etc - * on the "mirror" schedule rather than the "client" schedule. - */ -int -directory_fetches_dir_info_early(const or_options_t *options) -{ - return directory_fetches_from_authorities(options); -} - -/** Return 1 if we should fetch new networkstatuses, descriptors, etc - * on a very passive schedule -- waiting long enough for ordinary clients - * to probably have the info we want. These would include bridge users, - * and maybe others in the future e.g. if a Tor client uses another Tor - * client as a directory guard. - */ -int -directory_fetches_dir_info_later(const or_options_t *options) -{ - return options->UseBridges != 0; -} + * as a directory mirror */ /** Return true iff we want to serve certificates for authorities * that we don't acknowledge as authorities ourself. @@ -160,19 +112,6 @@ directory_permits_begindir_requests(const or_options_t *options) return options->BridgeRelay != 0 || dir_server_mode(options); } -/** Return 1 if we have no need to fetch new descriptors. This generally - * happens when we're not a dir cache and we haven't built any circuits - * lately. - */ -int -directory_too_idle_to_fetch_descriptors(const or_options_t *options, - time_t now) -{ - return !directory_caches_dir_info(options) && - !options->FetchUselessDescriptors && - rep_hist_circbuilding_dormant(now); -} - /********************************************************************/ /** Map from flavor name to the cached_dir_t for the v3 consensuses that we're diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h index 895cef9484..29c5b9ad2c 100644 --- a/src/feature/dircache/dirserv.h +++ b/src/feature/dircache/dirserv.h @@ -80,14 +80,9 @@ int dir_split_resource_into_spoolable(const char *resource, int *compressed_out, int flags); -int directory_fetches_from_authorities(const or_options_t *options); -int directory_fetches_dir_info_early(const or_options_t *options); -int directory_fetches_dir_info_later(const or_options_t *options); int directory_caches_unknown_auth_certs(const or_options_t *options); int directory_caches_dir_info(const or_options_t *options); int directory_permits_begindir_requests(const or_options_t *options); -int directory_too_idle_to_fetch_descriptors(const or_options_t *options, - time_t now); MOCK_DECL(cached_dir_t *, dirserv_get_consensus, (const char *flavor_name)); void dirserv_set_cached_consensus_networkstatus(const char *consensus, diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 721b0f8d1a..200e4e6a15 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -25,6 +25,7 @@ #include "feature/dirauth/shared_random.h" #include "feature/dircache/dirserv.h" #include "feature/dirclient/dirclient.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/dirclient/dlstatus.h" #include "feature/dircommon/consdiff.h" #include "feature/dircommon/directory.h" diff --git a/src/feature/dirclient/dirclient_modes.c b/src/feature/dirclient/dirclient_modes.c new file mode 100644 index 0000000000..37d2d7e044 --- /dev/null +++ b/src/feature/dirclient/dirclient_modes.c @@ -0,0 +1,85 @@ +/* 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. */ +/* See LICENSE for licensing information */ + +/** + * @file dirclient_modes.c + * @brief Functions to answer questions about how we'd like to behave + * as a directory client + **/ + +#include "orconfig.h" + +#include "core/or/or.h" + +#include "feature/dirclient/dirclient_modes.h" +#include "feature/dircache/dirserv.h" +#include "feature/relay/router.h" +#include "feature/relay/routermode.h" +#include "feature/stats/predict_ports.h" + +#include "app/config/or_options_st.h" +#include "feature/nodelist/routerinfo_st.h" + +/** Return 1 if we fetch our directory material directly from the + * authorities, rather than from a mirror. */ +int +directory_fetches_from_authorities(const or_options_t *options) +{ + const routerinfo_t *me; + uint32_t addr; + int refuseunknown; + if (options->FetchDirInfoEarly) + return 1; + if (options->BridgeRelay == 1) + return 0; + if (server_mode(options) && + router_pick_published_address(options, &addr, 1) < 0) + return 1; /* we don't know our IP address; ask an authority. */ + refuseunknown = ! router_my_exit_policy_is_reject_star() && + should_refuse_unknown_exits(options); + if (!dir_server_mode(options) && !refuseunknown) + return 0; + if (!server_mode(options) || !advertised_server_mode()) + return 0; + me = router_get_my_routerinfo(); + if (!me || (!me->supports_tunnelled_dir_requests && !refuseunknown)) + return 0; /* if we don't service directory requests, return 0 too */ + return 1; +} + +/** Return 1 if we should fetch new networkstatuses, descriptors, etc + * on the "mirror" schedule rather than the "client" schedule. + */ +int +directory_fetches_dir_info_early(const or_options_t *options) +{ + return directory_fetches_from_authorities(options); +} + +/** Return 1 if we should fetch new networkstatuses, descriptors, etc + * on a very passive schedule -- waiting long enough for ordinary clients + * to probably have the info we want. These would include bridge users, + * and maybe others in the future e.g. if a Tor client uses another Tor + * client as a directory guard. + */ +int +directory_fetches_dir_info_later(const or_options_t *options) +{ + return options->UseBridges != 0; +} + +/** Return 1 if we have no need to fetch new descriptors. This generally + * happens when we're not a dir cache and we haven't built any circuits + * lately. + */ +int +directory_too_idle_to_fetch_descriptors(const or_options_t *options, + time_t now) +{ + return !directory_caches_dir_info(options) && + !options->FetchUselessDescriptors && + rep_hist_circbuilding_dormant(now); +} diff --git a/src/feature/dirclient/dirclient_modes.h b/src/feature/dirclient/dirclient_modes.h new file mode 100644 index 0000000000..ceb883038c --- /dev/null +++ b/src/feature/dirclient/dirclient_modes.h @@ -0,0 +1,23 @@ +/* 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. */ +/* See LICENSE for licensing information */ + +/** + * @file dirclient_modes.h + * @brief Header for feature/dirclient/dirclient_modes.c + **/ + +#ifndef TOR_FEATURE_DIRCLIENT_DIRCLIENT_MODES_H +#define TOR_FEATURE_DIRCLIENT_DIRCLIENT_MODES_H + +struct or_options_t; + +int directory_fetches_from_authorities(const struct or_options_t *options); +int directory_fetches_dir_info_early(const struct or_options_t *options); +int directory_fetches_dir_info_later(const struct or_options_t *options); +int directory_too_idle_to_fetch_descriptors(const struct or_options_t *options, + time_t now); + +#endif /* !defined(TOR_FEATURE_DIRCLIENT_DIRCLIENT_MODES_H) */ diff --git a/src/feature/nodelist/microdesc.c b/src/feature/nodelist/microdesc.c index 39cffcf3a9..a2b95dd1ff 100644 --- a/src/feature/nodelist/microdesc.c +++ b/src/feature/nodelist/microdesc.c @@ -18,6 +18,7 @@ #include "feature/client/entrynodes.h" #include "feature/dircache/dirserv.h" #include "feature/dirclient/dlstatus.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/dircommon/directory.h" #include "feature/dirparse/microdesc_parse.h" #include "feature/nodelist/dirlist.h" diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c index 7868020477..2758dbc271 100644 --- a/src/feature/nodelist/networkstatus.c +++ b/src/feature/nodelist/networkstatus.c @@ -63,6 +63,7 @@ #include "feature/dircache/consdiffmgr.h" #include "feature/dircache/dirserv.h" #include "feature/dirclient/dirclient.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/dirclient/dlstatus.h" #include "feature/dircommon/directory.h" #include "feature/dircommon/voting_schedule.h" diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index 04c290613b..49b8c87327 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -51,7 +51,7 @@ #include "feature/client/entrynodes.h" #include "feature/control/control_events.h" #include "feature/dirauth/process_descs.h" -#include "feature/dircache/dirserv.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/hs/hs_client.h" #include "feature/hs/hs_common.h" #include "feature/nodelist/describe.h" diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c index e6457191bf..8caa0df11c 100644 --- a/src/feature/nodelist/routerlist.c +++ b/src/feature/nodelist/routerlist.c @@ -73,6 +73,7 @@ #include "feature/dirauth/reachability.h" #include "feature/dircache/dirserv.h" #include "feature/dirclient/dirclient.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/dirclient/dlstatus.h" #include "feature/dircommon/directory.h" #include "feature/nodelist/authcert.h" diff --git a/src/test/test_config.c b/src/test/test_config.c index 39af34b1ee..771c008413 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -28,6 +28,7 @@ #include "feature/control/control.h" #include "core/mainloop/cpuworker.h" #include "feature/dircache/dirserv.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/dirauth/dirvote.h" #include "feature/relay/dns.h" #include "feature/client/entrynodes.h" From 8d1f31190e12d337ef37c5ba541b195d72dfd663 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 15 Jan 2020 11:55:16 -0500 Subject: [PATCH 08/12] Move directory_must_use_begindir() to dirclient_modes.[ch] --- src/feature/dirclient/dirclient.c | 10 ---------- src/feature/dirclient/dirclient.h | 2 -- src/feature/dirclient/dirclient_modes.c | 10 ++++++++++ src/feature/dirclient/dirclient_modes.h | 1 + src/feature/nodelist/node_select.c | 1 + 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 200e4e6a15..2291bf730c 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -872,16 +872,6 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status) update_certificate_downloads(time(NULL)); } -/* Should this tor instance only use begindir for all its directory requests? - */ -int -directory_must_use_begindir(const or_options_t *options) -{ - /* Clients, onion services, and bridges must use begindir, - * relays and authorities do not have to */ - return !public_server_mode(options); -} - /** Evaluate the situation and decide if we should use an encrypted * "begindir-style" connection for this directory request. * 0) If there is no DirPort, yes. diff --git a/src/feature/dirclient/dirclient.h b/src/feature/dirclient/dirclient.h index 7c2a539ef7..08209721bb 100644 --- a/src/feature/dirclient/dirclient.h +++ b/src/feature/dirclient/dirclient.h @@ -41,8 +41,6 @@ typedef enum { DIRIND_ANON_DIRPORT, } dir_indirection_t; -int directory_must_use_begindir(const or_options_t *options); - /** * A directory_request_t describes the information about a directory request * at the client side. It describes what we're going to ask for, which diff --git a/src/feature/dirclient/dirclient_modes.c b/src/feature/dirclient/dirclient_modes.c index 37d2d7e044..8a98f02769 100644 --- a/src/feature/dirclient/dirclient_modes.c +++ b/src/feature/dirclient/dirclient_modes.c @@ -23,6 +23,16 @@ #include "app/config/or_options_st.h" #include "feature/nodelist/routerinfo_st.h" +/* Should this tor instance only use begindir for all its directory requests? + */ +int +directory_must_use_begindir(const or_options_t *options) +{ + /* Clients, onion services, and bridges must use begindir, + * relays and authorities do not have to */ + return !public_server_mode(options); +} + /** Return 1 if we fetch our directory material directly from the * authorities, rather than from a mirror. */ int diff --git a/src/feature/dirclient/dirclient_modes.h b/src/feature/dirclient/dirclient_modes.h index ceb883038c..f8ff74b6c1 100644 --- a/src/feature/dirclient/dirclient_modes.h +++ b/src/feature/dirclient/dirclient_modes.h @@ -14,6 +14,7 @@ struct or_options_t; +int directory_must_use_begindir(const or_options_t *options); int directory_fetches_from_authorities(const struct or_options_t *options); int directory_fetches_dir_info_early(const struct or_options_t *options); int directory_fetches_dir_info_later(const struct or_options_t *options); diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c index 3da972fb8c..8ca4fd5dba 100644 --- a/src/feature/nodelist/node_select.c +++ b/src/feature/nodelist/node_select.c @@ -19,6 +19,7 @@ #include "core/or/reasons.h" #include "feature/client/entrynodes.h" #include "feature/dirclient/dirclient.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/dircommon/directory.h" #include "feature/nodelist/describe.h" #include "feature/nodelist/dirlist.h" From 6ba4b5e5da9089a061ed64c0e172e72f71c11e75 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 15 Jan 2020 11:57:49 -0500 Subject: [PATCH 09/12] Rename dirclient_modes.h identifiers to start with dirclient_ This is an automated commit, generated by this command: ./scripts/maint/rename_c_identifier.py \ directory_must_use_begindir dirclient_must_use_begindir \ directory_fetches_from_authorities dirclient_fetches_from_authorities \ directory_fetches_dir_info_early dirclient_fetches_dir_info_early \ directory_fetches_dir_info_later dirclient_fetches_dir_info_later \ directory_too_idle_to_fetch_descriptors dirclient_too_idle_to_fetch_descriptors --- src/app/config/config.c | 8 ++++---- src/core/mainloop/mainloop.c | 6 +++--- src/feature/dirclient/dirclient.c | 12 ++++++------ src/feature/dirclient/dirclient_modes.c | 12 ++++++------ src/feature/dirclient/dirclient_modes.h | 10 +++++----- src/feature/nodelist/microdesc.c | 2 +- src/feature/nodelist/networkstatus.c | 6 +++--- src/feature/nodelist/node_select.c | 4 ++-- src/feature/nodelist/nodelist.c | 2 +- src/feature/nodelist/routerlist.c | 6 +++--- src/test/test_config.c | 26 ++++++++++++------------- 11 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/app/config/config.c b/src/app/config/config.c index f9bfb05125..9a5bb5265f 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -2419,10 +2419,10 @@ options_act,(const or_options_t *old_options)) /* We may need to reschedule some directory stuff if our status changed. */ if (old_options) { - if (!bool_eq(directory_fetches_dir_info_early(options), - directory_fetches_dir_info_early(old_options)) || - !bool_eq(directory_fetches_dir_info_later(options), - directory_fetches_dir_info_later(old_options)) || + if (!bool_eq(dirclient_fetches_dir_info_early(options), + dirclient_fetches_dir_info_early(old_options)) || + !bool_eq(dirclient_fetches_dir_info_later(options), + dirclient_fetches_dir_info_later(old_options)) || !config_lines_eq(old_options->Bridges, options->Bridges)) { /* Make sure update_router_have_minimum_dir_info() gets called. */ router_dir_info_changed(); diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index 230bf4a25f..7781b29fb1 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -1133,14 +1133,14 @@ directory_info_has_arrived(time_t now, int from_cache, int suppress_logs) if (!router_have_minimum_dir_info()) { int quiet = suppress_logs || from_cache || - directory_too_idle_to_fetch_descriptors(options, now); + dirclient_too_idle_to_fetch_descriptors(options, now); tor_log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR, "I learned some more directory information, but not enough to " "build a circuit: %s", get_dir_info_status_string()); update_all_descriptor_downloads(now); return; } else { - if (directory_fetches_from_authorities(options)) { + if (dirclient_fetches_from_authorities(options)) { update_all_descriptor_downloads(now); } @@ -2069,7 +2069,7 @@ fetch_networkstatus_callback(time_t now, const or_options_t *options) * documents? */ const int we_are_bootstrapping = networkstatus_consensus_is_bootstrapping( now); - const int prefer_mirrors = !directory_fetches_from_authorities( + const int prefer_mirrors = !dirclient_fetches_from_authorities( get_options()); int networkstatus_dl_check_interval = 60; /* check more often when testing, or when bootstrapping from mirrors diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 2291bf730c..1b6eed12f0 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -454,7 +454,7 @@ directory_get_from_dirserver,( { const routerstatus_t *rs = NULL; const or_options_t *options = get_options(); - int prefer_authority = (directory_fetches_from_authorities(options) + int prefer_authority = (dirclient_fetches_from_authorities(options) || want_authority == DL_WANT_AUTHORITY); int require_authority = 0; int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose, @@ -673,7 +673,7 @@ directory_choose_address_routerstatus(const routerstatus_t *status, if (indirection == DIRIND_DIRECT_CONN || indirection == DIRIND_ANON_DIRPORT || (indirection == DIRIND_ONEHOP - && !directory_must_use_begindir(options))) { + && !dirclient_must_use_begindir(options))) { fascist_firewall_choose_address_rs(status, FIREWALL_DIR_CONNECTION, 0, use_dir_ap); have_dir = tor_addr_port_is_valid_ap(use_dir_ap, 0); @@ -923,7 +923,7 @@ directory_command_should_use_begindir(const or_options_t *options, } /* Reasons why we want to avoid using begindir */ if (indirection == DIRIND_ONEHOP) { - if (!directory_must_use_begindir(options)) { + if (!dirclient_must_use_begindir(options)) { *reason = "in relay mode"; return 0; } @@ -1285,7 +1285,7 @@ directory_initiate_request,(directory_request_t *request)) /* use encrypted begindir connections for everything except relays * this provides better protection for directory fetches */ - if (!use_begindir && directory_must_use_begindir(options)) { + if (!use_begindir && dirclient_must_use_begindir(options)) { log_warn(LD_BUG, "Client could not use begindir connection: %s", begindir_reason ? begindir_reason : "(NULL)"); return; @@ -3084,7 +3084,7 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code, { char digest[DIGEST_LEN]; time_t now = time(NULL); - int server = directory_fetches_from_authorities(get_options()); + int server = dirclient_fetches_from_authorities(get_options()); if (!was_descriptor_digests) { if (router_purpose == ROUTER_PURPOSE_BRIDGE) { tor_assert(!was_extrainfo); @@ -3129,7 +3129,7 @@ dir_microdesc_download_failed(smartlist_t *failed, routerstatus_t *rs; download_status_t *dls; time_t now = time(NULL); - int server = directory_fetches_from_authorities(get_options()); + int server = dirclient_fetches_from_authorities(get_options()); if (! consensus) return; diff --git a/src/feature/dirclient/dirclient_modes.c b/src/feature/dirclient/dirclient_modes.c index 8a98f02769..23fd1a2f6e 100644 --- a/src/feature/dirclient/dirclient_modes.c +++ b/src/feature/dirclient/dirclient_modes.c @@ -26,7 +26,7 @@ /* Should this tor instance only use begindir for all its directory requests? */ int -directory_must_use_begindir(const or_options_t *options) +dirclient_must_use_begindir(const or_options_t *options) { /* Clients, onion services, and bridges must use begindir, * relays and authorities do not have to */ @@ -36,7 +36,7 @@ directory_must_use_begindir(const or_options_t *options) /** Return 1 if we fetch our directory material directly from the * authorities, rather than from a mirror. */ int -directory_fetches_from_authorities(const or_options_t *options) +dirclient_fetches_from_authorities(const or_options_t *options) { const routerinfo_t *me; uint32_t addr; @@ -64,9 +64,9 @@ directory_fetches_from_authorities(const or_options_t *options) * on the "mirror" schedule rather than the "client" schedule. */ int -directory_fetches_dir_info_early(const or_options_t *options) +dirclient_fetches_dir_info_early(const or_options_t *options) { - return directory_fetches_from_authorities(options); + return dirclient_fetches_from_authorities(options); } /** Return 1 if we should fetch new networkstatuses, descriptors, etc @@ -76,7 +76,7 @@ directory_fetches_dir_info_early(const or_options_t *options) * client as a directory guard. */ int -directory_fetches_dir_info_later(const or_options_t *options) +dirclient_fetches_dir_info_later(const or_options_t *options) { return options->UseBridges != 0; } @@ -86,7 +86,7 @@ directory_fetches_dir_info_later(const or_options_t *options) * lately. */ int -directory_too_idle_to_fetch_descriptors(const or_options_t *options, +dirclient_too_idle_to_fetch_descriptors(const or_options_t *options, time_t now) { return !directory_caches_dir_info(options) && diff --git a/src/feature/dirclient/dirclient_modes.h b/src/feature/dirclient/dirclient_modes.h index f8ff74b6c1..c402207724 100644 --- a/src/feature/dirclient/dirclient_modes.h +++ b/src/feature/dirclient/dirclient_modes.h @@ -14,11 +14,11 @@ struct or_options_t; -int directory_must_use_begindir(const or_options_t *options); -int directory_fetches_from_authorities(const struct or_options_t *options); -int directory_fetches_dir_info_early(const struct or_options_t *options); -int directory_fetches_dir_info_later(const struct or_options_t *options); -int directory_too_idle_to_fetch_descriptors(const struct or_options_t *options, +int dirclient_must_use_begindir(const or_options_t *options); +int dirclient_fetches_from_authorities(const struct or_options_t *options); +int dirclient_fetches_dir_info_early(const struct or_options_t *options); +int dirclient_fetches_dir_info_later(const struct or_options_t *options); +int dirclient_too_idle_to_fetch_descriptors(const struct or_options_t *options, time_t now); #endif /* !defined(TOR_FEATURE_DIRCLIENT_DIRCLIENT_MODES_H) */ diff --git a/src/feature/nodelist/microdesc.c b/src/feature/nodelist/microdesc.c index a2b95dd1ff..d32a4ea61e 100644 --- a/src/feature/nodelist/microdesc.c +++ b/src/feature/nodelist/microdesc.c @@ -998,7 +998,7 @@ update_microdesc_downloads(time_t now) if (should_delay_dir_fetches(options, NULL)) return; - if (directory_too_idle_to_fetch_descriptors(options, now)) + if (dirclient_too_idle_to_fetch_descriptors(options, now)) return; /* Give up if we don't have a reasonably live consensus. */ diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c index 2758dbc271..61220d6164 100644 --- a/src/feature/nodelist/networkstatus.c +++ b/src/feature/nodelist/networkstatus.c @@ -1163,7 +1163,7 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav) } } - if (directory_fetches_dir_info_early(options)) { + if (dirclient_fetches_dir_info_early(options)) { /* We want to cache the next one at some point after this one * is no longer fresh... */ start = (time_t)(c->fresh_until + min_sec_before_caching); @@ -1185,7 +1185,7 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav) /* If we're a bridge user, make use of the numbers we just computed * to choose the rest of the interval *after* them. */ - if (directory_fetches_dir_info_later(options)) { + if (dirclient_fetches_dir_info_later(options)) { /* Give all the *clients* enough time to download the consensus. */ start = (time_t)(start + dl_interval + min_sec_before_caching); /* But try to get it before ours actually expires. */ @@ -1538,7 +1538,7 @@ networkstatus_consensus_can_use_extra_fallbacks,(const or_options_t *options)) >= smartlist_len(router_get_trusted_dir_servers())); /* If we don't fetch from the authorities, and we have additional mirrors, * we can use them. */ - return (!directory_fetches_from_authorities(options) + return (!dirclient_fetches_from_authorities(options) && (smartlist_len(router_get_fallback_dir_servers()) > smartlist_len(router_get_trusted_dir_servers()))); } diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c index 8ca4fd5dba..d959021c4a 100644 --- a/src/feature/nodelist/node_select.c +++ b/src/feature/nodelist/node_select.c @@ -323,7 +323,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags, const int skip_or_fw = router_skip_or_reachability(options, try_ip_pref); const int skip_dir_fw = router_skip_dir_reachability(options, try_ip_pref); - const int must_have_or = directory_must_use_begindir(options); + const int must_have_or = dirclient_must_use_begindir(options); /* Find all the running dirservers we know about. */ SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) { @@ -1076,7 +1076,7 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist, const int skip_or_fw = router_skip_or_reachability(options, try_ip_pref); const int skip_dir_fw = router_skip_dir_reachability(options, try_ip_pref); - const int must_have_or = directory_must_use_begindir(options); + const int must_have_or = dirclient_must_use_begindir(options); SMARTLIST_FOREACH_BEGIN(sourcelist, const dir_server_t *, d) { diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index 49b8c87327..94ff08826f 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -2752,7 +2752,7 @@ update_router_have_minimum_dir_info(void) /* If paths have just become unavailable in this update. */ if (!res && have_min_dir_info) { - int quiet = directory_too_idle_to_fetch_descriptors(options, now); + int quiet = dirclient_too_idle_to_fetch_descriptors(options, now); tor_log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR, "Our directory information is no longer up-to-date " "enough to build circuits: %s", dir_info_status); diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c index 8caa0df11c..9ccad55734 100644 --- a/src/feature/nodelist/routerlist.c +++ b/src/feature/nodelist/routerlist.c @@ -2405,7 +2405,7 @@ max_dl_per_request(const or_options_t *options, int purpose) } /* If we're going to tunnel our connections, we can ask for a lot more * in a request. */ - if (directory_must_use_begindir(options)) { + if (dirclient_must_use_begindir(options)) { max = 500; } return max; @@ -2448,7 +2448,7 @@ launch_descriptor_downloads(int purpose, if (!n_downloadable) return; - if (!directory_fetches_dir_info_early(options)) { + if (!dirclient_fetches_dir_info_early(options)) { if (n_downloadable >= MAX_DL_TO_DELAY) { log_debug(LD_DIR, "There are enough downloadable %ss to launch requests.", @@ -2539,7 +2539,7 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote, int n_delayed=0, n_have=0, n_would_reject=0, n_wouldnt_use=0, n_inprogress=0, n_in_oldrouters=0; - if (directory_too_idle_to_fetch_descriptors(options, now)) + if (dirclient_too_idle_to_fetch_descriptors(options, now)) goto done; if (!consensus) goto done; diff --git a/src/test/test_config.c b/src/test/test_config.c index 771c008413..25ba6f6fde 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -3706,7 +3706,7 @@ test_config_directory_fetch(void *arg) options->ClientOnly = 1; tt_assert(server_mode(options) == 0); tt_assert(public_server_mode(options) == 0); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 0); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 0); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 1); @@ -3716,7 +3716,7 @@ test_config_directory_fetch(void *arg) options->UseBridges = 1; tt_assert(server_mode(options) == 0); tt_assert(public_server_mode(options) == 0); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 0); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 0); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 1); @@ -3728,7 +3728,7 @@ test_config_directory_fetch(void *arg) options->ORPort_set = 1; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 0); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 0); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 0); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 1); @@ -3739,7 +3739,7 @@ test_config_directory_fetch(void *arg) options->FetchDirInfoEarly = 1; tt_assert(server_mode(options) == 0); tt_assert(public_server_mode(options) == 0); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 1); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 1); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 1); @@ -3753,14 +3753,14 @@ test_config_directory_fetch(void *arg) mock_router_pick_published_address_result = -1; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 1); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 1); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); mock_router_pick_published_address_result = 0; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 0); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 0); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); @@ -3781,7 +3781,7 @@ test_config_directory_fetch(void *arg) options->RefuseUnknownExits = 1; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 1); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 1); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); @@ -3789,7 +3789,7 @@ test_config_directory_fetch(void *arg) mock_router_pick_published_address_result = 0; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 0); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 0); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); @@ -3811,7 +3811,7 @@ test_config_directory_fetch(void *arg) mock_router_get_my_routerinfo_result = &routerinfo; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 1); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 1); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); @@ -3820,7 +3820,7 @@ test_config_directory_fetch(void *arg) mock_router_get_my_routerinfo_result = &routerinfo; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 0); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 0); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); @@ -3828,7 +3828,7 @@ test_config_directory_fetch(void *arg) mock_router_get_my_routerinfo_result = NULL; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 0); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 0); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); @@ -3838,7 +3838,7 @@ test_config_directory_fetch(void *arg) mock_router_get_my_routerinfo_result = &routerinfo; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 0); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 0); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); @@ -3848,7 +3848,7 @@ test_config_directory_fetch(void *arg) mock_router_get_my_routerinfo_result = &routerinfo; tt_assert(server_mode(options) == 1); tt_assert(public_server_mode(options) == 1); - tt_int_op(directory_fetches_from_authorities(options), OP_EQ, 1); + tt_int_op(dirclient_fetches_from_authorities(options), OP_EQ, 1); tt_int_op(networkstatus_consensus_can_use_multiple_directories(options), OP_EQ, 0); From 5cff1ce84bf11d0a3abbfdda30dd3b96ce298c6b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 15 Jan 2020 12:30:43 -0500 Subject: [PATCH 10/12] Turn several functions from stubs into macros This may help the compiler eliminate deadcode. --- src/feature/dircache/dircache_stub.c | 44 ---------------------------- src/feature/dircache/dirserv.h | 22 +++++++++++++- 2 files changed, 21 insertions(+), 45 deletions(-) diff --git a/src/feature/dircache/dircache_stub.c b/src/feature/dircache/dircache_stub.c index f6804dad76..87811597d1 100644 --- a/src/feature/dircache/dircache_stub.c +++ b/src/feature/dircache/dircache_stub.c @@ -30,34 +30,6 @@ connection_dirserv_flushed_some(dir_connection_t *conn) return -1; } -int -directory_caches_unknown_auth_certs(const or_options_t *options) -{ - (void) options; - return 0; -} - -int -directory_caches_dir_info(const or_options_t *options) -{ - (void) options; - return 0; -} - -int -directory_permits_begindir_requests(const or_options_t *options) -{ - (void) options; - return 0; -} - -cached_dir_t * -dirserv_get_consensus(const char *flavor_name) -{ - (void) flavor_name; - return NULL; -} - void dir_conn_clear_spool(dir_connection_t *conn) { @@ -71,22 +43,6 @@ consdiffmgr_enable_background_compression(void) { } -void -dirserv_set_cached_consensus_networkstatus(const char *networkstatus, - size_t networkstatus_len, - const char *flavor_name, - const common_digests_t *digests, - const uint8_t *sha3_as_signed, - time_t published) -{ - (void)networkstatus; - (void)networkstatus_len; - (void)flavor_name; - (void)digests; - (void)sha3_as_signed; - (void)published; -} - int consdiffmgr_add_consensus(const char *consensus, size_t consensus_len, diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h index 29c5b9ad2c..a892d9ff87 100644 --- a/src/feature/dircache/dirserv.h +++ b/src/feature/dircache/dirserv.h @@ -80,10 +80,10 @@ int dir_split_resource_into_spoolable(const char *resource, int *compressed_out, int flags); +#ifdef HAVE_MODULE_DIRCACHE int directory_caches_unknown_auth_certs(const or_options_t *options); int directory_caches_dir_info(const or_options_t *options); int directory_permits_begindir_requests(const or_options_t *options); - MOCK_DECL(cached_dir_t *, dirserv_get_consensus, (const char *flavor_name)); void dirserv_set_cached_consensus_networkstatus(const char *consensus, size_t consensus_len, @@ -91,6 +91,26 @@ void dirserv_set_cached_consensus_networkstatus(const char *consensus, const common_digests_t *digests, const uint8_t *sha3_as_signed, time_t published); +#else +#define directory_caches_unknown_auth_certs(opt) \ + ((void)(opt), 0) +#define directory_caches_dir_info(opt) \ + ((void)(opt), 0) +#define directory_permits_begindir_requests(opt) \ + ((void)(opt), 0) +#define dirserv_get_consensus(flav) \ + ((void)(flav), NULL) +#define dirserv_set_cached_consensus_networkstatus(a,b,c,d,e,f) \ + STMT_BEGIN { \ + (void)(a); \ + (void)(b); \ + (void)(c); \ + (void)(d); \ + (void)(e); \ + (void)(f); \ + } STMT_END +#endif + void dirserv_clear_old_networkstatuses(time_t cutoff); int dirserv_get_routerdesc_spool(smartlist_t *spools_out, const char *key, dir_spool_source_t source, From a623a497778324c4aba570be4217c723d6a3010f Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 15 Jan 2020 12:45:56 -0500 Subject: [PATCH 11/12] Add have_module_dircache(). --- src/feature/dircache/dirserv.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h index a892d9ff87..3a168c2035 100644 --- a/src/feature/dircache/dirserv.h +++ b/src/feature/dircache/dirserv.h @@ -81,6 +81,8 @@ int dir_split_resource_into_spoolable(const char *resource, int flags); #ifdef HAVE_MODULE_DIRCACHE +/** Is the dircache module enabled? */ +#define have_module_dircache() (1) int directory_caches_unknown_auth_certs(const or_options_t *options); int directory_caches_dir_info(const or_options_t *options); int directory_permits_begindir_requests(const or_options_t *options); @@ -92,6 +94,7 @@ void dirserv_set_cached_consensus_networkstatus(const char *consensus, const uint8_t *sha3_as_signed, time_t published); #else +#define have_module_dircache() (0) #define directory_caches_unknown_auth_certs(opt) \ ((void)(opt), 0) #define directory_caches_dir_info(opt) \ From efb301c86c288c01e21dfb5da9f685f33341b2c2 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 15 Jan 2020 12:46:10 -0500 Subject: [PATCH 12/12] Document why dircache is not included in --list-modules --- configure.ac | 2 +- src/app/config/config.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 85ffc1c752..4571768d8e 100644 --- a/configure.ac +++ b/configure.ac @@ -290,7 +290,7 @@ AM_COND_IF(BUILD_MODULE_RELAY, [Compile with Relay feature support])) dnl Dircache module. (This cannot be enabled or disabled independently of -dnl the relay module.) +dnl the relay module. It is not listed by --list-modules for this reason.) AM_CONDITIONAL(BUILD_MODULE_DIRCACHE, [test "x$enable_module_relay" != "xno"]) AM_COND_IF(BUILD_MODULE_DIRCACHE, diff --git a/src/app/config/config.c b/src/app/config/config.c index 9a5bb5265f..1d41500890 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -2733,6 +2733,9 @@ list_enabled_modules(void) { printf("%s: %s\n", "relay", have_module_relay() ? "yes" : "no"); printf("%s: %s\n", "dirauth", have_module_dirauth() ? "yes" : "no"); + // We don't list dircache, because it cannot be enabled or disabled + // independently from relay. Listing it here would proliferate + // test variants in test_parseconf.sh to no useful purpose. } /** Last value actually set by resolve_my_address. */