summaryrefslogtreecommitdiff
path: root/src/or/routerlist.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-04-27 14:36:30 -0400
committerNick Mathewson <nickm@torproject.org>2011-04-27 14:36:30 -0400
commit8b686d98c47226dfc4d7c87d6a472b592135ae07 (patch)
tree06df10f204230dc1be42abec946430b8d20f084f /src/or/routerlist.c
parent3256627a4548c4977b834cc724689e0e9a960f06 (diff)
parent99621bc5a629a81a5a823ce21ac3d967443d0e12 (diff)
downloadtor-8b686d98c47226dfc4d7c87d6a472b592135ae07.tar.gz
tor-8b686d98c47226dfc4d7c87d6a472b592135ae07.zip
Merge maint-0.2.2 for the bug1090-part1-squashed branch
Resolved conflicts in: doc/tor.1.txt src/or/circuitbuild.c src/or/circuituse.c src/or/connection_edge.c src/or/connection_edge.h src/or/directory.c src/or/rendclient.c src/or/routerlist.c src/or/routerlist.h These were mostly releated to the routerinfo_t->node_t conversion.
Diffstat (limited to 'src/or/routerlist.c')
-rw-r--r--src/or/routerlist.c73
1 files changed, 63 insertions, 10 deletions
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 8c68a34cca..d5dc478388 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1075,6 +1075,7 @@ router_pick_trusteddirserver(authority_type_t type, int flags)
static const routerstatus_t *
router_pick_directory_server_impl(authority_type_t type, int flags)
{
+ or_options_t *options = get_options();
const node_t *result;
smartlist_t *direct, *tunnel;
smartlist_t *trusted_direct, *trusted_tunnel;
@@ -1084,10 +1085,13 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
int requireother = ! (flags & PDS_ALLOW_SELF);
int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL);
int prefer_tunnel = (flags & _PDS_PREFER_TUNNELED_DIR_CONNS);
+ int try_excluding = 1, n_excluded = 0;
if (!consensus)
return NULL;
+ retry_without_exclude:
+
direct = smartlist_create();
tunnel = smartlist_create();
trusted_direct = smartlist_create();
@@ -1101,6 +1105,7 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
int is_overloaded;
tor_addr_t addr;
const routerstatus_t *status = node->rs;
+ const country_t country = node->country;
if (!status)
continue;
@@ -1122,6 +1127,12 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
if ((type & EXTRAINFO_CACHE) &&
!router_supports_extrainfo(node->identity, 0))
continue;
+ if (try_excluding && options->ExcludeNodes &&
+ routerset_contains_routerstatus(options->ExcludeNodes, status,
+ country)) {
+ ++n_excluded;
+ continue;
+ }
/* XXXX IP6 proposal 118 */
tor_addr_from_ipv4h(&addr, node->rs->addr);
@@ -1165,6 +1176,15 @@ router_pick_directory_server_impl(authority_type_t type, int flags)
smartlist_free(trusted_tunnel);
smartlist_free(overloaded_direct);
smartlist_free(overloaded_tunnel);
+
+ if (result == NULL && try_excluding && !options->StrictNodes && n_excluded) {
+ /* If we got no result, and we are excluding nodes, and StrictNodes is
+ * not set, try again without excluding nodes. */
+ try_excluding = 0;
+ n_excluded = 0;
+ goto retry_without_exclude;
+ }
+
return result ? result->rs : NULL;
}
@@ -1175,6 +1195,7 @@ static const routerstatus_t *
router_pick_trusteddirserver_impl(authority_type_t type, int flags,
int *n_busy_out)
{
+ or_options_t *options = get_options();
smartlist_t *direct, *tunnel;
smartlist_t *overloaded_direct, *overloaded_tunnel;
const routerinfo_t *me = router_get_my_routerinfo();
@@ -1186,10 +1207,13 @@ router_pick_trusteddirserver_impl(authority_type_t type, int flags,
const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH);
const int no_microdesc_fetching =(flags & PDS_NO_EXISTING_MICRODESC_FETCH);
int n_busy = 0;
+ int try_excluding = 1, n_excluded = 0;
if (!trusted_dir_servers)
return NULL;
+ retry_without_exclude:
+
direct = smartlist_create();
tunnel = smartlist_create();
overloaded_direct = smartlist_create();
@@ -1208,6 +1232,12 @@ router_pick_trusteddirserver_impl(authority_type_t type, int flags,
continue;
if (requireother && me && router_digest_is_me(d->digest))
continue;
+ if (try_excluding && options->ExcludeNodes &&
+ routerset_contains_routerstatus(options->ExcludeNodes,
+ &d->fake_status, -1)) {
+ ++n_excluded;
+ continue;
+ }
/* XXXX IP6 proposal 118 */
tor_addr_from_ipv4h(&addr, d->addr);
@@ -1261,6 +1291,15 @@ router_pick_trusteddirserver_impl(authority_type_t type, int flags,
smartlist_free(tunnel);
smartlist_free(overloaded_direct);
smartlist_free(overloaded_tunnel);
+
+ if (result == NULL && try_excluding && !options->StrictNodes && n_excluded) {
+ /* If we got no result, and we are excluding nodes, and StrictNodes is
+ * not set, try again without excluding nodes. */
+ try_excluding = 0;
+ n_excluded = 0;
+ goto retry_without_exclude;
+ }
+
return result;
}
@@ -1367,7 +1406,7 @@ nodelist_add_node_family(smartlist_t *sl, const node_t *node)
if (options->NodeFamilySets) {
SMARTLIST_FOREACH(options->NodeFamilySets, const routerset_t *, rs, {
if (routerset_contains_node(rs, node)) {
- routerset_get_all_nodes(sl, rs, 0);
+ routerset_get_all_nodes(sl, rs, NULL, 0);
}
});
}
@@ -1512,6 +1551,8 @@ routerlist_find_my_routerinfo(void)
/** Find a router that's up, that has this IP address, and
* that allows exit to this address:port, or return NULL if there
* isn't a good one.
+ * Don't exit enclave to excluded relays -- it wouldn't actually
+ * hurt anything, but this way there are fewer confused users.
*/
const node_t *
router_find_exact_exit_enclave(const char *address, uint16_t port)
@@ -1519,6 +1560,7 @@ router_find_exact_exit_enclave(const char *address, uint16_t port)
uint32_t addr;
struct in_addr in;
tor_addr_t a;
+ or_options_t *options = get_options();
if (!tor_inet_aton(address, &in))
return NULL; /* it's not an IP already */
@@ -1530,7 +1572,8 @@ router_find_exact_exit_enclave(const char *address, uint16_t port)
if (node_get_addr_ipv4h(node) == addr &&
node->is_running &&
compare_tor_addr_to_node_policy(&a, port, node) ==
- ADDR_POLICY_ACCEPTED)
+ ADDR_POLICY_ACCEPTED &&
+ !routerset_contains_node(options->_ExcludeExitNodesUnion, node))
return node;
});
return NULL;
@@ -5484,7 +5527,7 @@ routerset_needs_geoip(const routerset_t *set)
}
/** Return true iff there are no entries in <b>set</b>. */
-static int
+int
routerset_is_empty(const routerset_t *set)
{
return !set || smartlist_len(set->list) == 0;
@@ -5580,10 +5623,11 @@ routerset_contains_node(const routerset_t *set, const node_t *node)
}
/** Add every known node_t that is a member of <b>routerset</b> to
- * <b>out</b>. If <b>running_only</b>, only add the running ones. */
+ * <b>out</b>, but never add any that are part of <b>excludeset</b>.
+ * If <b>running_only</b>, only add the running ones. */
void
routerset_get_all_nodes(smartlist_t *out, const routerset_t *routerset,
- int running_only)
+ const routerset_t *excludeset, int running_only)
{ /* XXXX MOVE */
tor_assert(out);
if (!routerset || !routerset->list)
@@ -5591,12 +5635,13 @@ routerset_get_all_nodes(smartlist_t *out, const routerset_t *routerset,
if (routerset_is_list(routerset)) {
/* No routers are specified by type; all are given by name or digest.
- * we can do a lookup in O(len(list)). */
+ * we can do a lookup in O(len(routerset)). */
SMARTLIST_FOREACH(routerset->list, const char *, name, {
const node_t *node = node_get_by_nickname(name, 1);
if (node) {
if (!running_only || node->is_running)
- smartlist_add(out, (void*)node);
+ if (!routerset_contains_node(excludeset, node))
+ smartlist_add(out, (void*)node);
}
});
} else {
@@ -5606,12 +5651,14 @@ routerset_get_all_nodes(smartlist_t *out, const routerset_t *routerset,
SMARTLIST_FOREACH(nodes, const node_t *, node, {
if (running_only && !node->is_running)
continue;
- if (routerset_contains_node(routerset, node))
+ if (routerset_contains_node(routerset, node) &&
+ !routerset_contains_node(excludeset, node))
smartlist_add(out, (void*)node);
});
}
}
+#if 0
/** Add to <b>target</b> every node_t from <b>source</b> except:
*
* 1) Don't add it if <b>include</b> is non-empty and the relay isn't in
@@ -5642,6 +5689,7 @@ routersets_get_node_disjunction(smartlist_t *target,
}
});
}
+#endif
/** Remove every node_t from <b>lst</b> that is in <b>routerset</b>. */
void
@@ -5673,10 +5721,15 @@ routerset_to_string(const routerset_t *set)
int
routerset_equal(const routerset_t *old, const routerset_t *new)
{
- if (old == NULL && new == NULL)
+ if (routerset_is_empty(old) && routerset_is_empty(new)) {
+ /* Two empty sets are equal */
return 1;
- else if (old == NULL || new == NULL)
+ } else if (routerset_is_empty(old) || routerset_is_empty(new)) {
+ /* An empty set is equal to nothing else. */
return 0;
+ }
+ tor_assert(old != NULL);
+ tor_assert(new != NULL);
if (smartlist_len(old->list) != smartlist_len(new->list))
return 0;