[tor-commits] [tor/master] Optimise reachability checks when iterating through relay lists
nickm at torproject.org
nickm at torproject.org
Thu Feb 11 17:37:18 UTC 2016
commit 772577b547aa5e6b13b89f465acf656cd08f2917
Author: teor (Tim Wilson-Brown) <teor2345 at gmail.com>
Date: Thu Jan 21 13:30:57 2016 +1100
Optimise reachability checks when iterating through relay lists
Skip address checks on servers.
Skip allowed-only address checks on non-bridge clients with IPv4.
---
src/or/policies.c | 4 ++++
src/or/routerlist.c | 55 +++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/src/or/policies.c b/src/or/policies.c
index 506edec..0dc4f96 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -323,6 +323,8 @@ firewall_is_fascist_impl(void)
/** Return true iff the firewall options, including ClientUseIPv4 0 and
* ClientUseIPv6 0, might block any OR address:port combination.
+ * Address preferences may still change which address is selected even if
+ * this function returns false.
*/
int
firewall_is_fascist_or(void)
@@ -332,6 +334,8 @@ firewall_is_fascist_or(void)
/** Return true iff the firewall options, including ClientUseIPv4 0 and
* ClientUseIPv6 0, might block any Dir address:port combination.
+ * Address preferences may still change which address is selected even if
+ * this function returns false.
*/
int
firewall_is_fascist_dir(void)
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 247818d..9b8885e 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1623,6 +1623,30 @@ router_picked_poor_directory_log(const routerstatus_t *rs)
} \
STMT_END
+/* When iterating through the routerlist, can OR address/port preference
+ * and reachability checks be skipped?
+ */
+static int
+router_skip_or_reachability(const or_options_t *options, int try_ip_pref)
+{
+ /* Servers always have and prefer IPv4.
+ * And if clients are checking against the firewall for reachability only,
+ * but there's no firewall, don't bother checking */
+ return server_mode(options) || (!try_ip_pref && !firewall_is_fascist_or());
+}
+
+/* When iterating through the routerlist, can Dir address/port preference
+ * and reachability checks be skipped?
+ */
+static int
+router_skip_dir_reachability(const or_options_t *options, int try_ip_pref)
+{
+ /* Servers always have and prefer IPv4.
+ * And if clients are checking against the firewall for reachability only,
+ * but there's no firewall, don't bother checking */
+ return server_mode(options) || (!try_ip_pref && !firewall_is_fascist_dir());
+}
+
/** Pick a random running valid directory server/mirror from our
* routerlist. Arguments are as for router_pick_directory_server(), except:
*
@@ -1661,6 +1685,9 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
overloaded_direct = smartlist_new();
overloaded_tunnel = smartlist_new();
+ const int skip_or = router_skip_or_reachability(options, try_ip_pref);
+ const int skip_dir = router_skip_dir_reachability(options, try_ip_pref);
+
/* Find all the running dirservers we know about. */
SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) {
int is_trusted, is_trusted_extrainfo;
@@ -1704,18 +1731,20 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
- /* We use an IPv6 address if we have one and we prefer it.
+ /* Clients use IPv6 addresses if the server has one and the client
+ * prefers IPv6.
* Add the router if its preferred address and port are reachable.
* If we don't get any routers, we'll try again with the non-preferred
* address for each router (if any). (To ensure correct load-balancing
* we try routers that only have one address both times.)
*/
- if (!fascistfirewall ||
+ if (!fascistfirewall || skip_or ||
fascist_firewall_allows_rs(status, FIREWALL_OR_CONNECTION,
try_ip_pref))
smartlist_add(is_trusted ? trusted_tunnel :
is_overloaded ? overloaded_tunnel : tunnel, (void*)node);
- else if (fascist_firewall_allows_rs(status, FIREWALL_DIR_CONNECTION,
+ else if (skip_dir ||
+ fascist_firewall_allows_rs(status, FIREWALL_DIR_CONNECTION,
try_ip_pref))
smartlist_add(is_trusted ? trusted_direct :
is_overloaded ? overloaded_direct : direct, (void*)node);
@@ -1820,6 +1849,9 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist,
overloaded_direct = smartlist_new();
overloaded_tunnel = smartlist_new();
+ const int skip_or = router_skip_or_reachability(options, try_ip_pref);
+ const int skip_dir = router_skip_dir_reachability(options, try_ip_pref);
+
SMARTLIST_FOREACH_BEGIN(sourcelist, const dir_server_t *, d)
{
int is_overloaded =
@@ -1845,17 +1877,19 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist,
continue;
}
- /* We use an IPv6 address if we have one and we prefer it.
+ /* Clients use IPv6 addresses if the server has one and the client
+ * prefers IPv6.
* Add the router if its preferred address and port are reachable.
* If we don't get any routers, we'll try again with the non-preferred
* address for each router (if any). (To ensure correct load-balancing
* we try routers that only have one address both times.)
*/
- if (!fascistfirewall ||
+ if (!fascistfirewall || skip_or ||
fascist_firewall_allows_dir_server(d, FIREWALL_OR_CONNECTION,
try_ip_pref))
smartlist_add(is_overloaded ? overloaded_tunnel : tunnel, (void*)d);
- else if (fascist_firewall_allows_dir_server(d, FIREWALL_DIR_CONNECTION,
+ else if (skip_dir ||
+ fascist_firewall_allows_dir_server(d, FIREWALL_DIR_CONNECTION,
try_ip_pref))
smartlist_add(is_overloaded ? overloaded_direct : direct, (void*)d);
else if (!tor_addr_is_null(&d->ipv6_addr))
@@ -1965,7 +1999,10 @@ router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
int need_uptime, int need_capacity,
int need_guard, int need_desc,
int pref_addr)
-{ /* XXXX MOVE */
+{
+ const int check_reach = !router_skip_or_reachability(get_options(),
+ pref_addr);
+ /* XXXX MOVE */
SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) {
if (!node->is_running ||
(!node->is_valid && !allow_invalid))
@@ -1977,7 +2014,9 @@ router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
if (node_is_unreliable(node, need_uptime, need_capacity, need_guard))
continue;
/* Choose a node with an OR address that matches the firewall rules */
- if (!fascist_firewall_allows_node(node, FIREWALL_OR_CONNECTION, pref_addr))
+ if (check_reach && !fascist_firewall_allows_node(node,
+ FIREWALL_OR_CONNECTION,
+ pref_addr))
continue;
smartlist_add(sl, (void *)node);
More information about the tor-commits
mailing list