aboutsummaryrefslogtreecommitdiff
path: root/src/or/router.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-05-17 10:48:12 -0400
committerNick Mathewson <nickm@torproject.org>2016-05-17 10:48:12 -0400
commit548d14247e3c8a48e2efb2ca62ee7a05fca843ba (patch)
tree461e46b28ff628235379dfa242fa44b1ca1eccfa /src/or/router.c
parent6cc3397e26ff37d6f01471b83e0e5bb1b5aa8eee (diff)
parent06031b441eb92f575f0a1c2ac264dc0daee4fbf4 (diff)
downloadtor-548d14247e3c8a48e2efb2ca62ee7a05fca843ba.tar.gz
tor-548d14247e3c8a48e2efb2ca62ee7a05fca843ba.zip
Merge remote-tracking branch 'arma/bug18616-v4' into maint-0.2.8
Diffstat (limited to 'src/or/router.c')
-rw-r--r--src/or/router.c140
1 files changed, 99 insertions, 41 deletions
diff --git a/src/or/router.c b/src/or/router.c
index 3f94703a26..d70756fdbf 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1079,23 +1079,49 @@ router_reset_reachability(void)
can_reach_or_port = can_reach_dir_port = 0;
}
-/** Return 1 if ORPort is known reachable; else return 0. */
-int
-check_whether_orport_reachable(void)
+/** Return 1 if we won't do reachability checks, because:
+ * - AssumeReachable is set, or
+ * - the network is disabled.
+ * Otherwise, return 0.
+ */
+static int
+router_reachability_checks_disabled(const or_options_t *options)
{
- const or_options_t *options = get_options();
return options->AssumeReachable ||
+ net_is_disabled();
+}
+
+/** Return 0 if we need to do an ORPort reachability check, because:
+ * - no reachability check has been done yet, or
+ * - we've initiated reachability checks, but none have succeeded.
+ * Return 1 if we don't need to do an ORPort reachability check, because:
+ * - we've seen a successful reachability check, or
+ * - AssumeReachable is set, or
+ * - the network is disabled.
+ */
+int
+check_whether_orport_reachable(const or_options_t *options)
+{
+ int reach_checks_disabled = router_reachability_checks_disabled(options);
+ return reach_checks_disabled ||
can_reach_or_port;
}
-/** Return 1 if we don't have a dirport configured, or if it's reachable. */
+/** Return 0 if we need to do a DirPort reachability check, because:
+ * - no reachability check has been done yet, or
+ * - we've initiated reachability checks, but none have succeeded.
+ * Return 1 if we don't need to do a DirPort reachability check, because:
+ * - we've seen a successful reachability check, or
+ * - there is no DirPort set, or
+ * - AssumeReachable is set, or
+ * - the network is disabled.
+ */
int
-check_whether_dirport_reachable(void)
+check_whether_dirport_reachable(const or_options_t *options)
{
- const or_options_t *options = get_options();
- return !options->DirPort_set ||
- options->AssumeReachable ||
- net_is_disabled() ||
+ int reach_checks_disabled = router_reachability_checks_disabled(options) ||
+ !options->DirPort_set;
+ return reach_checks_disabled ||
can_reach_dir_port;
}
@@ -1148,10 +1174,11 @@ router_should_be_directory_server(const or_options_t *options, int dir_port)
"seconds long. Raising to 1.");
interval_length = 1;
}
- log_info(LD_GENERAL, "Calculating whether to disable dirport: effective "
+ log_info(LD_GENERAL, "Calculating whether to advertise %s: effective "
"bwrate: %u, AccountingMax: "U64_FORMAT", "
- "accounting interval length %d", effective_bw,
- U64_PRINTF_ARG(options->AccountingMax),
+ "accounting interval length %d",
+ dir_port ? "dirport" : "begindir",
+ effective_bw, U64_PRINTF_ARG(options->AccountingMax),
interval_length);
acc_bytes = options->AccountingMax;
@@ -1199,34 +1226,62 @@ dir_server_mode(const or_options_t *options)
}
/** Look at a variety of factors, and return 0 if we don't want to
- * advertise the fact that we have a DirPort open, else return the
- * DirPort we want to advertise.
+ * advertise the fact that we have a DirPort open or begindir support, else
+ * return 1.
*
- * Log a helpful message if we change our mind about whether to publish
- * a DirPort.
+ * Where dir_port or supports_tunnelled_dir_requests are not relevant, they
+ * must be 0.
+ *
+ * Log a helpful message if we change our mind about whether to publish.
*/
static int
-decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
+decide_to_advertise_dir_impl(const or_options_t *options,
+ uint16_t dir_port,
+ int supports_tunnelled_dir_requests)
{
/* Part one: reasons to publish or not publish that aren't
* worth mentioning to the user, either because they're obvious
* or because they're normal behavior. */
- if (!dir_port) /* short circuit the rest of the function */
+ /* short circuit the rest of the function */
+ if (!dir_port && !supports_tunnelled_dir_requests)
return 0;
if (authdir_mode(options)) /* always publish */
- return dir_port;
+ return 1;
if (net_is_disabled())
return 0;
- if (!check_whether_dirport_reachable())
+ if (dir_port && !router_get_advertised_dir_port(options, dir_port))
return 0;
- if (!router_get_advertised_dir_port(options, dir_port))
+ if (supports_tunnelled_dir_requests &&
+ !router_get_advertised_or_port(options))
return 0;
- /* Part two: reasons to publish or not publish that the user
- * might find surprising. router_should_be_directory_server()
- * considers config options that make us choose not to publish. */
- return router_should_be_directory_server(options, dir_port) ? dir_port : 0;
+ /* Part two: consider config options that could make us choose to
+ * publish or not publish that the user might find surprising. */
+ return router_should_be_directory_server(options, dir_port);
+}
+
+/** Front-end to decide_to_advertise_dir_impl(): return 0 if we don't want to
+ * advertise the fact that we have a DirPort open, else return the
+ * DirPort we want to advertise.
+ */
+static int
+decide_to_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;
+}
+
+/** Front-end to decide_to_advertise_dir_impl(): return 0 if we don't want to
+ * advertise the fact that we support begindir requests, else return 1.
+ */
+static int
+decide_to_advertise_begindir(const or_options_t *options,
+ int supports_tunnelled_dir_requests)
+{
+ /* dir_port is not relevant, pass 0 */
+ return decide_to_advertise_dir_impl(options, 0,
+ supports_tunnelled_dir_requests);
}
/** Allocate and return a new extend_info_t that can be used to build
@@ -1260,9 +1315,9 @@ void
consider_testing_reachability(int test_or, int test_dir)
{
const routerinfo_t *me = router_get_my_routerinfo();
- int orport_reachable = check_whether_orport_reachable();
- tor_addr_t addr;
const or_options_t *options = get_options();
+ int orport_reachable = check_whether_orport_reachable(options);
+ tor_addr_t addr;
if (!me)
return;
@@ -1295,7 +1350,7 @@ consider_testing_reachability(int test_or, int test_dir)
/* XXX IPv6 self testing */
tor_addr_from_ipv4h(&addr, me->addr);
- if (test_dir && !check_whether_dirport_reachable() &&
+ if (test_dir && !check_whether_dirport_reachable(options) &&
!connection_get_by_type_addr_port_purpose(
CONN_TYPE_DIR, &addr, me->dir_port,
DIR_PURPOSE_FETCH_SERVERDESC)) {
@@ -1314,18 +1369,19 @@ void
router_orport_found_reachable(void)
{
const routerinfo_t *me = router_get_my_routerinfo();
+ const or_options_t *options = get_options();
if (!can_reach_or_port && me) {
char *address = tor_dup_ip(me->addr);
log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
"the outside. Excellent.%s",
- get_options()->PublishServerDescriptor_ != NO_DIRINFO
- && check_whether_dirport_reachable() ?
+ options->PublishServerDescriptor_ != NO_DIRINFO
+ && check_whether_dirport_reachable(options) ?
" Publishing server descriptor." : "");
can_reach_or_port = 1;
mark_my_descriptor_dirty("ORPort found reachable");
/* This is a significant enough change to upload immediately,
* at least in a test network */
- if (get_options()->TestingTorNetwork == 1) {
+ if (options->TestingTorNetwork == 1) {
reschedule_descriptor_update_check();
}
control_event_server_status(LOG_NOTICE,
@@ -1340,19 +1396,20 @@ void
router_dirport_found_reachable(void)
{
const routerinfo_t *me = router_get_my_routerinfo();
+ const or_options_t *options = get_options();
if (!can_reach_dir_port && me) {
char *address = tor_dup_ip(me->addr);
log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
"from the outside. Excellent.%s",
- get_options()->PublishServerDescriptor_ != NO_DIRINFO
- && check_whether_orport_reachable() ?
+ options->PublishServerDescriptor_ != NO_DIRINFO
+ && check_whether_orport_reachable(options) ?
" Publishing server descriptor." : "");
can_reach_dir_port = 1;
- if (decide_to_advertise_dirport(get_options(), me->dir_port)) {
+ if (decide_to_advertise_dirport(options, me->dir_port)) {
mark_my_descriptor_dirty("DirPort found reachable");
/* This is a significant enough change to upload immediately,
* at least in a test network */
- if (get_options()->TestingTorNetwork == 1) {
+ if (options->TestingTorNetwork == 1) {
reschedule_descriptor_update_check();
}
}
@@ -1570,14 +1627,14 @@ decide_if_publishable_server(void)
return 1;
if (!router_get_advertised_or_port(options))
return 0;
- if (!check_whether_orport_reachable())
+ if (!check_whether_orport_reachable(options))
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();
+ return check_whether_dirport_reachable(options);
}
}
@@ -1933,8 +1990,8 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
ri->addr = addr;
ri->or_port = router_get_advertised_or_port(options);
ri->dir_port = router_get_advertised_dir_port(options, 0);
- ri->supports_tunnelled_dir_requests = dir_server_mode(options) &&
- router_should_be_directory_server(options, ri->dir_port);
+ ri->supports_tunnelled_dir_requests =
+ directory_permits_begindir_requests(options);
ri->cache_info.published_on = time(NULL);
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
* main thread */
@@ -2715,7 +2772,8 @@ router_dump_router_to_string(routerinfo_t *router,
tor_free(p6);
}
- if (router->supports_tunnelled_dir_requests) {
+ if (decide_to_advertise_begindir(options,
+ router->supports_tunnelled_dir_requests)) {
smartlist_add(chunks, tor_strdup("tunnelled-dir-server\n"));
}