summaryrefslogtreecommitdiff
path: root/src/or/nodelist.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-04-16 10:38:55 -0400
committerNick Mathewson <nickm@torproject.org>2018-04-22 19:42:26 -0400
commit948dd2c79ea9ca1fd06c13f275515a1745c46986 (patch)
treeafc311f00bca225b6745b4778a73f38d741c6eb9 /src/or/nodelist.c
parent22845df2a7503ed73ed325c3a98916f289918caa (diff)
downloadtor-948dd2c79ea9ca1fd06c13f275515a1745c46986.tar.gz
tor-948dd2c79ea9ca1fd06c13f275515a1745c46986.zip
Check for "the right descriptor", not just "any descriptor".
This patch adds a new node_has_preferred_descriptor() function, and replaces most users of node_has_descriptor() with it. That's an important change, since as of d1874b433953f64 (our fix for #25213), we are willing to say that a node has _some_ descriptor, but not the _right_ descriptor for a particular use case. Part of a fix for 25691 and 25692.
Diffstat (limited to 'src/or/nodelist.c')
-rw-r--r--src/or/nodelist.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 3a26aee611..2962d3cb40 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -43,6 +43,7 @@
#include "or.h"
#include "address.h"
#include "address_set.h"
+#include "bridges.h"
#include "config.h"
#include "control.h"
#include "dirserv.h"
@@ -1139,6 +1140,32 @@ node_has_descriptor(const node_t *node)
(node->rs && node->md));
}
+/** Return true iff <b>node</b> has the kind of descriptor we would prefer to
+ * use for it, given our configuration and how we intend to use the node.
+ *
+ * If <b>for_direct_connect</b> is true, we intend to connect to the node
+ * directly, as the first hop of a circuit; otherwise, we intend to connect to
+ * it indirectly, or use it as if we were connecting to it indirectly. */
+int
+node_has_preferred_descriptor(const node_t *node,
+ int for_direct_connect)
+{
+ const int is_bridge = node_is_a_configured_bridge(node);
+ const int we_use_mds = we_use_microdescriptors_for_circuits(get_options());
+
+ if ((is_bridge && for_direct_connect) || !we_use_mds) {
+ /* We need an ri in this case. */
+ if (!node->ri)
+ return 0;
+ } else {
+ /* Otherwise we need an rs and an md. */
+ if (node->rs == NULL || node->md == NULL)
+ return 0;
+ }
+
+ return 1;
+}
+
/** Return the router_purpose of <b>node</b>. */
int
node_get_purpose(const node_t *node)
@@ -2221,7 +2248,8 @@ compute_frac_paths_available(const networkstatus_t *consensus,
nu);
SMARTLIST_FOREACH_BEGIN(myexits_unflagged, const node_t *, node) {
- if (node_has_descriptor(node) && node_exit_policy_rejects_all(node)) {
+ if (node_has_preferred_descriptor(node, 0) &&
+ node_exit_policy_rejects_all(node)) {
SMARTLIST_DEL_CURRENT(myexits_unflagged, node);
/* this node is not actually an exit */
np--;