aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-04-03 19:43:47 -0400
committerNick Mathewson <nickm@torproject.org>2011-04-26 23:54:17 -0400
commit80adb3de507db4cd67208396e1ea301f131c1228 (patch)
treef2ada6125e306bfdf4baea7ea8f373043fd162b8
parent128582cc1f9fd363f3fb2a96b61fde1701a56970 (diff)
downloadtor-80adb3de507db4cd67208396e1ea301f131c1228.tar
tor-80adb3de507db4cd67208396e1ea301f131c1228.tar.gz
When there is a transition in permitted nodes, apply it to trackexithosts map
IOW, if we were using TrackExitHosts, and we added an excluded node or removed a node from exitnodes, we wouldn't actually remove the mapping that points us at the new node. Also, note with an XXX022 comment a place that I think we are looking at the wrong string.
-rw-r--r--src/or/config.c1
-rw-r--r--src/or/connection_edge.c54
-rw-r--r--src/or/connection_edge.h1
-rw-r--r--src/or/routerlist.c2
-rw-r--r--src/or/routerlist.h1
5 files changed, 55 insertions, 4 deletions
diff --git a/src/or/config.c b/src/or/config.c
index 44cde85dc..f003e4d29 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1271,6 +1271,7 @@ options_act(or_options_t *old_options)
"excluded node lists. Abandoning previous circuits.");
circuit_mark_all_unused_circs();
circuit_expire_all_dirty_circs();
+ addressmap_clear_excluded_trackexithosts(options);
}
/* How long should we delay counting bridge stats after becoming a bridge?
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index f435976a4..5f322cae2 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -789,9 +789,6 @@ addressmap_ent_remove(const char *address, addressmap_entry_t *ent)
static void
clear_trackexithost_mappings(const char *exitname)
{
- /* XXXX022-1090 We need a variant of this that clears all mappings no longer
- permitted because of changes to the ExcludeNodes, ExitNodes, or
- ExcludeExitNodes settings. */
char *suffix;
size_t suffix_len;
if (!addressmap || !exitname)
@@ -802,6 +799,7 @@ clear_trackexithost_mappings(const char *exitname)
tor_strlower(suffix);
STRMAP_FOREACH_MODIFY(addressmap, address, addressmap_entry_t *, ent) {
+ /* XXXX022 HEY! Shouldn't this look at ent->new_address? */
if (ent->source == ADDRMAPSRC_TRACKEXIT && !strcmpend(address, suffix)) {
addressmap_ent_remove(address, ent);
MAP_DEL_CURRENT(address);
@@ -811,6 +809,56 @@ clear_trackexithost_mappings(const char *exitname)
tor_free(suffix);
}
+/** Remove all TRACKEXIT mappings from the addressmap for which the target
+ * host is unknown or no longer allowed. */
+void
+addressmap_clear_excluded_trackexithosts(or_options_t *options)
+{
+ const routerset_t *allow_nodes = options->ExitNodes;
+ const routerset_t *exclude_nodes = options->_ExcludeExitNodesUnion;
+
+ if (!addressmap)
+ return;
+ if (routerset_is_empty(allow_nodes))
+ allow_nodes = NULL;
+ if (allow_nodes == NULL && routerset_is_empty(exclude_nodes))
+ return;
+
+ STRMAP_FOREACH_MODIFY(addressmap, address, addressmap_entry_t *, ent) {
+ size_t len;
+ const char *target = ent->new_address, *dot;
+ char *nodename;
+ routerinfo_t *ri; /* XXX023 Use node_t. */
+
+ if (strcmpend(target, ".exit")) {
+ /* Not a .exit mapping */
+ continue;
+ } else if (ent->source != ADDRMAPSRC_TRACKEXIT) {
+ /* Not a trackexit mapping. */
+ continue;
+ }
+ len = strlen(target);
+ if (len < 6)
+ continue; /* malformed. */
+ dot = target + len - 6; /* dot now points to just before .exit */
+ dot = strrchr(dot, '.'); /* dot now points to the . before .exit, or NULL */
+ if (!dot) {
+ nodename = tor_strndup(target, len-5);
+ } else {
+ nodename = tor_strndup(dot+1, strlen(dot+1)-5);
+ }
+ ri = router_get_by_nickname(nodename, 0);
+ tor_free(nodename);
+ if (!ri ||
+ (allow_nodes && !routerset_contains_router(allow_nodes, ri)) ||
+ routerset_contains_router(exclude_nodes, ri)) {
+ /* We don't know this one, or we want to be rid of it. */
+ addressmap_ent_remove(address, ent);
+ MAP_DEL_CURRENT(address);
+ }
+ } STRMAP_FOREACH_END;
+}
+
/** Remove all entries from the addressmap that were set via the
* configuration file or the command line. */
void
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index 0b08dd07c..c4ae46751 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -62,6 +62,7 @@ int connection_ap_process_transparent(edge_connection_t *conn);
int address_is_invalid_destination(const char *address, int client);
void addressmap_init(void);
+void addressmap_clear_excluded_trackexithosts(or_options_t *options);
void addressmap_clean(time_t now);
void addressmap_clear_configured(void);
void addressmap_clear_transient(void);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index d5e8a6b05..d9f099b4f 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -5474,7 +5474,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;
diff --git a/src/or/routerlist.h b/src/or/routerlist.h
index 3bbdc42eb..fec18705b 100644
--- a/src/or/routerlist.h
+++ b/src/or/routerlist.h
@@ -167,6 +167,7 @@ int routerset_parse(routerset_t *target, const char *s,
void routerset_union(routerset_t *target, const routerset_t *source);
int routerset_is_list(const routerset_t *set);
int routerset_needs_geoip(const routerset_t *set);
+int routerset_is_empty(const routerset_t *set);
int routerset_contains_router(const routerset_t *set, routerinfo_t *ri);
int routerset_contains_routerstatus(const routerset_t *set,
routerstatus_t *rs);