aboutsummaryrefslogtreecommitdiff
path: root/src/or/nodelist.c
diff options
context:
space:
mode:
authorteor (Tim Wilson-Brown) <teor2345@gmail.com>2016-01-04 00:35:22 +1100
committerteor (Tim Wilson-Brown) <teor2345@gmail.com>2016-01-29 07:16:04 +1100
commit3b8216f2155f224bf66497c71de4cecb55cd83e6 (patch)
treed20a3e81663bfafb73020acd78343640f12ce54a /src/or/nodelist.c
parent4528f893163ad7ab27915451caf23b3a722413ce (diff)
downloadtor-3b8216f2155f224bf66497c71de4cecb55cd83e6.tar.gz
tor-3b8216f2155f224bf66497c71de4cecb55cd83e6.zip
Use fascist firewall and ClientUseIPv4 for bridge clients
Bridge clients ignore ClientUseIPv6, acting as if it is always 1. This preserves existing behaviour. Make ClientPreferIPv6OR/DirPort auto by default: * Bridge clients prefer IPv6 by default. * Other clients prefer IPv4 by default. This preserves existing behaviour.
Diffstat (limited to 'src/or/nodelist.c')
-rw-r--r--src/or/nodelist.c156
1 files changed, 56 insertions, 100 deletions
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 7ca1146e86..c8f93bf30c 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -214,76 +214,6 @@ nodelist_add_microdesc(microdesc_t *md)
return node;
}
-/** Do we prefer to connect to IPv6, ignoring ClientPreferIPv6ORPort and
- * ClientPreferIPv6DirPort?
- * If we're unsure, return -1, otherwise, return 1 for IPv6 and 0 for IPv4.
- */
-static int
-nodelist_prefer_ipv6(const or_options_t *options)
-{
- /*
- Cheap implementation of config options ClientUseIPv4 & ClientUseIPv6 --
- If we're a server, use IPv4.
- If we're a client running with bridges, use IPv6.
- Otherwise, use IPv6 if we can and it's preferred, or if IPv4 is disabled.
- See #4455 and #17840 for more on this subject.
- */
-
- /* Servers prefer IPv4 */
- if (server_mode(options)) {
- return 0;
- }
-
- /* Bridge clients prefer IPv6 */
- if (options->UseBridges) {
- return 1;
- }
-
- if (!options->ClientUseIPv4) {
- return 1;
- }
-
- return -1;
-}
-
-/** Do we prefer to connect to IPv6 ORPorts?
- */
-int
-nodelist_prefer_ipv6_orport(const or_options_t *options)
-{
- int pref_ipv6 = nodelist_prefer_ipv6(options);
-
- if (pref_ipv6 >= 0) {
- return pref_ipv6;
- }
-
- /* We prefer IPv6 ORPorts if the option is set */
- if (options->ClientUseIPv6 && options->ClientPreferIPv6ORPort) {
- return 1;
- }
-
- return 0;
-}
-
-/** Do we prefer to connect to IPv6 DirPorts?
- */
-int
-nodelist_prefer_ipv6_dirport(const or_options_t *options)
-{
- int pref_ipv6 = nodelist_prefer_ipv6(options);
-
- if (pref_ipv6 >= 0) {
- return pref_ipv6;
- }
-
- /* We prefer IPv6 DirPorts if the option is set */
- if (options->ClientUseIPv6 && options->ClientPreferIPv6DirPort) {
- return 1;
- }
-
- return 0;
-}
-
/** Tell the nodelist that the current usable consensus is <b>ns</b>.
* This makes the nodelist change all of the routerstatus entries for
* the nodes, drop nodes that no longer have enough info to get used,
@@ -330,7 +260,7 @@ nodelist_set_consensus(networkstatus_t *ns)
node->is_bad_exit = rs->is_bad_exit;
node->is_hs_dir = rs->is_hs_dir;
node->ipv6_preferred = 0;
- if (nodelist_prefer_ipv6_orport(options) &&
+ if (fascist_firewall_prefer_ipv6_orport(options) &&
(tor_addr_is_null(&rs->ipv6_addr) == 0 ||
(node->md && tor_addr_is_null(&node->md->ipv6_addr) == 0)))
node->ipv6_preferred = 1;
@@ -916,9 +846,13 @@ node_get_addr(const node_t *node, tor_addr_t *addr_out)
uint32_t
node_get_prim_addr_ipv4h(const node_t *node)
{
- if (node->ri) {
+ /* Don't check the ORPort or DirPort, as this function isn't port-specific,
+ * and the node might have a valid IPv4 address, yet have a zero
+ * ORPort or DirPort.
+ */
+ if (node->ri && tor_addr_is_valid_ipv4h(node->ri->addr, 0)) {
return node->ri->addr;
- } else if (node->rs) {
+ } else if (node->rs && tor_addr_is_valid_ipv4h(node->rs->addr, 0)) {
return node->rs->addr;
}
return 0;
@@ -994,20 +928,44 @@ node_get_declared_family(const node_t *node)
return NULL;
}
-/* Does this node have a valid IPv6 address? */
-static int
+/* Does this node have a valid IPv6 address?
+ * Prefer node_has_ipv6_orport() or node_has_ipv6_dirport() for
+ * checking specific ports. */
+int
node_has_ipv6_addr(const node_t *node)
{
- if (node->ri)
- return !tor_addr_is_null(&node->ri->ipv6_addr);
- if (node->md)
- return !tor_addr_is_null(&node->md->ipv6_addr);
- if (node->rs)
- return !tor_addr_is_null(&node->rs->ipv6_addr);
+ /* Don't check the ORPort or DirPort, as this function isn't port-specific,
+ * and the node might have a valid IPv6 address, yet have a zero
+ * ORPort or DirPort.
+ */
+ if (node->ri && tor_addr_is_valid(&node->ri->ipv6_addr, 0))
+ return 1;
+ if (node->rs && tor_addr_is_valid(&node->rs->ipv6_addr, 0))
+ return 1;
+ if (node->md && tor_addr_is_valid(&node->md->ipv6_addr, 0))
+ return 1;
return 0;
}
+/* Does this node have a valid IPv6 ORPort? */
+int
+node_has_ipv6_orport(const node_t *node)
+{
+ tor_addr_port_t ipv6_orport;
+ node_get_pref_ipv6_orport(node, &ipv6_orport);
+ return tor_addr_port_is_valid_ap(&ipv6_orport, 0);
+}
+
+/* Does this node have a valid IPv6 DirPort? */
+int
+node_has_ipv6_dirport(const node_t *node)
+{
+ tor_addr_port_t ipv6_dirport;
+ node_get_pref_ipv6_dirport(node, &ipv6_dirport);
+ return tor_addr_port_is_valid_ap(&ipv6_dirport, 0);
+}
+
/** Return 1 if we prefer the IPv6 address and OR TCP port of
* <b>node</b>, else 0.
*
@@ -1028,20 +986,18 @@ node_ipv6_or_preferred(const node_t *node)
tor_addr_port_t ipv4_addr;
node_assert_ok(node);
- if (!options->ClientUseIPv6) {
+ if (!fascist_firewall_use_ipv6(options)) {
return 0;
} else if (node->ipv6_preferred || node_get_prim_orport(node, &ipv4_addr)
- || nodelist_prefer_ipv6_orport(get_options())) {
- return node_has_ipv6_addr(node);
+ || fascist_firewall_prefer_ipv6_orport(get_options())) {
+ return node_has_ipv6_orport(node);
}
return 0;
}
#define RETURN_IPV4_AP(r, port_field, ap_out) \
STMT_BEGIN \
- if (r) { \
- if ((r)->addr == 0 || (r)->port_field == 0) \
- return -1; \
+ if (r && tor_addr_port_is_valid_ipv4h((r)->addr, (r)->port_field, 0)) { \
tor_addr_from_ipv4h(&(ap_out)->addr, (r)->addr); \
(ap_out)->port = (r)->port_field; \
return 0; \
@@ -1091,16 +1047,16 @@ node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out)
* fascist_firewall_* functions. Also check if the address or port are valid,
* and try another alternative if they are not. */
- if (node->ri && node->ri->ipv6_orport
- && !tor_addr_is_null(&node->ri->ipv6_addr)) {
+ if (node->ri && tor_addr_port_is_valid(&node->ri->ipv6_addr,
+ node->ri->ipv6_orport, 0)) {
tor_addr_copy(&ap_out->addr, &node->ri->ipv6_addr);
ap_out->port = node->ri->ipv6_orport;
- } else if (node->rs && node->rs->ipv6_orport
- && !tor_addr_is_null(&node->rs->ipv6_addr)) {
+ } else if (node->rs && tor_addr_port_is_valid(&node->rs->ipv6_addr,
+ node->rs->ipv6_orport, 0)) {
tor_addr_copy(&ap_out->addr, &node->rs->ipv6_addr);
ap_out->port = node->rs->ipv6_orport;
- } else if (node->md && node->md->ipv6_orport
- && !tor_addr_is_null(&node->md->ipv6_addr)) {
+ } else if (node->md && tor_addr_port_is_valid(&node->md->ipv6_addr,
+ node->md->ipv6_orport, 0)) {
tor_addr_copy(&ap_out->addr, &node->md->ipv6_addr);
ap_out->port = node->md->ipv6_orport;
} else {
@@ -1129,11 +1085,11 @@ node_ipv6_dir_preferred(const node_t *node)
tor_addr_port_t ipv4_addr;
node_assert_ok(node);
- if (!options->ClientUseIPv6) {
+ if (!fascist_firewall_use_ipv6(options)) {
return 0;
} else if (node->ipv6_preferred || node_get_prim_dirport(node, &ipv4_addr)
- || nodelist_prefer_ipv6_dirport(get_options())) {
- return node_has_ipv6_addr(node);
+ || fascist_firewall_prefer_ipv6_dirport(get_options())) {
+ return node_has_ipv6_dirport(node);
}
return 0;
}
@@ -1183,12 +1139,12 @@ node_get_pref_ipv6_dirport(const node_t *node, tor_addr_port_t *ap_out)
* they are not. Note that microdescriptors have no dir_port. */
/* Assume IPv4 and IPv6 dirports are the same */
- if (node->ri && node->ri->dir_port
- && !tor_addr_is_null(&node->ri->ipv6_addr)) {
+ if (node->ri && tor_addr_port_is_valid(&node->ri->ipv6_addr,
+ node->ri->dir_port, 0)) {
tor_addr_copy(&ap_out->addr, &node->ri->ipv6_addr);
ap_out->port = node->ri->dir_port;
- } else if (node->rs && node->rs->dir_port
- && !tor_addr_is_null(&node->rs->ipv6_addr)) {
+ } else if (node->rs && tor_addr_port_is_valid(&node->rs->ipv6_addr,
+ node->rs->dir_port, 0)) {
tor_addr_copy(&ap_out->addr, &node->rs->ipv6_addr);
ap_out->port = node->rs->dir_port;
} else {