aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-05-15 11:44:51 -0400
committerNick Mathewson <nickm@torproject.org>2011-05-15 11:44:51 -0400
commit37e3fb8af20b02f764d0993218ed6025448073dd (patch)
tree956927bb08f18e3f050cafdbc9c0c1f54a083d28 /src
parent2fd9cfdc234f5ec0d6799511be9ad7a57c52b45e (diff)
parentf2871009346e0589455be14e9cef930c19082c0a (diff)
downloadtor-37e3fb8af20b02f764d0993218ed6025448073dd.tar
tor-37e3fb8af20b02f764d0993218ed6025448073dd.tar.gz
Merge remote-tracking branch 'origin/maint-0.2.2'
Conflicts: src/or/connection_edge.c
Diffstat (limited to 'src')
-rw-r--r--src/common/container.c19
-rw-r--r--src/common/container.h2
-rw-r--r--src/or/circuituse.c51
-rw-r--r--src/or/circuituse.h2
-rw-r--r--src/or/config.c23
-rw-r--r--src/or/connection_edge.c51
-rw-r--r--src/or/connection_edge.h1
-rw-r--r--src/or/main.c1
-rw-r--r--src/or/or.h3
9 files changed, 126 insertions, 27 deletions
diff --git a/src/common/container.c b/src/common/container.c
index eba5a2f70..af80f881f 100644
--- a/src/common/container.c
+++ b/src/common/container.c
@@ -215,6 +215,25 @@ smartlist_string_num_isin(const smartlist_t *sl, int num)
return smartlist_string_isin(sl, buf);
}
+/** Return true iff the two lists contain the same strings in the same
+ * order, or if they are both NULL. */
+int
+smartlist_strings_eq(const smartlist_t *sl1, const smartlist_t *sl2)
+{
+ if (sl1 == NULL)
+ return sl2 == NULL;
+ if (sl2 == NULL)
+ return 0;
+ if (smartlist_len(sl1) != smartlist_len(sl2))
+ return 0;
+ SMARTLIST_FOREACH(sl1, const char *, cp1, {
+ const char *cp2 = smartlist_get(sl2, cp1_sl_idx);
+ if (strcmp(cp1, cp2))
+ return 0;
+ });
+ return 1;
+}
+
/** Return true iff <b>sl</b> has some element E such that
* tor_memeq(E,<b>element</b>,DIGEST_LEN)
*/
diff --git a/src/common/container.h b/src/common/container.h
index b39d4ca07..f5e42de76 100644
--- a/src/common/container.h
+++ b/src/common/container.h
@@ -42,6 +42,8 @@ int smartlist_string_pos(const smartlist_t *, const char *elt) ATTR_PURE;
int smartlist_string_isin_case(const smartlist_t *sl, const char *element)
ATTR_PURE;
int smartlist_string_num_isin(const smartlist_t *sl, int num) ATTR_PURE;
+int smartlist_strings_eq(const smartlist_t *sl1, const smartlist_t *sl2)
+ ATTR_PURE;
int smartlist_digest_isin(const smartlist_t *sl, const char *element)
ATTR_PURE;
int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2)
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 6e98e5383..f176f346f 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -1478,15 +1478,35 @@ link_apconn_to_circ(edge_connection_t *apconn, origin_circuit_t *circ,
}
}
-/** If an exit wasn't specifically chosen, save the history for future
- * use. */
+/** Return true iff <b>address</b> is matched by one of the entries in
+ * TrackHostExits. */
+int
+hostname_in_track_host_exits(or_options_t *options, const char *address)
+{
+ if (!options->TrackHostExits)
+ return 0;
+ SMARTLIST_FOREACH_BEGIN(options->TrackHostExits, const char *, cp) {
+ if (cp[0] == '.') { /* match end */
+ if (cp[1] == '\0' ||
+ !strcasecmpend(address, cp) ||
+ !strcasecmp(address, &cp[1]))
+ return 1;
+ } else if (strcasecmp(cp, address) == 0) {
+ return 1;
+ }
+ } SMARTLIST_FOREACH_END(cp);
+ return 0;
+}
+
+/** If an exit wasn't explicitly specified for <b>conn</b>, consider saving
+ * the exit that we *did* choose for use by future connections to
+ * <b>conn</b>'s destination.
+ */
static void
consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
{
- int found_needle = 0;
or_options_t *options = get_options();
- size_t len;
- char *new_address;
+ char *new_address = NULL;
char fp[HEX_DIGEST_LEN+1];
/* Search the addressmap for this conn's destination. */
@@ -1496,18 +1516,8 @@ consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
options->TrackHostExitsExpire))
return; /* nothing to track, or already mapped */
- SMARTLIST_FOREACH(options->TrackHostExits, const char *, cp, {
- if (cp[0] == '.') { /* match end */
- if (cp[1] == '\0' ||
- !strcasecmpend(conn->socks_request->address, cp) ||
- !strcasecmp(conn->socks_request->address, &cp[1]))
- found_needle = 1;
- } else if (strcasecmp(cp, conn->socks_request->address) == 0) {
- found_needle = 1;
- }
- });
-
- if (!found_needle || !circ->build_state->chosen_exit)
+ if (!hostname_in_track_host_exits(options, conn->socks_request->address) ||
+ !circ->build_state->chosen_exit)
return;
/* write down the fingerprint of the chosen exit, not the nickname,
@@ -1516,12 +1526,7 @@ consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
circ->build_state->chosen_exit->identity_digest, DIGEST_LEN);
/* Add this exit/hostname pair to the addressmap. */
- len = strlen(conn->socks_request->address) + 1 /* '.' */ +
- strlen(fp) + 1 /* '.' */ +
- strlen("exit") + 1 /* '\0' */;
- new_address = tor_malloc(len);
-
- tor_snprintf(new_address, len, "%s.%s.exit",
+ tor_asprintf(&new_address, "%s.%s.exit",
conn->socks_request->address, fp);
addressmap_register(conn->socks_request->address, new_address,
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index 1fdb19187..8e10212f1 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -50,5 +50,7 @@ int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
crypt_path_t *cpath);
int connection_ap_handshake_attach_circuit(edge_connection_t *conn);
+int hostname_in_track_host_exits(or_options_t *options, const char *address);
+
#endif
diff --git a/src/or/config.c b/src/or/config.c
index 1a877b8ed..f675379ad 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1285,6 +1285,8 @@ options_act(or_options_t *old_options)
/* Check for transitions that need action. */
if (old_options) {
+ int revise_trackexithosts = 0;
+ int revise_automap_entries = 0;
if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
!routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes) ||
!routerset_equal(old_options->ExcludeExitNodes,
@@ -1297,9 +1299,30 @@ options_act(or_options_t *old_options)
"excluded node lists. Abandoning previous circuits.");
circuit_mark_all_unused_circs();
circuit_expire_all_dirty_circs();
+ revise_trackexithosts = 1;
+ }
+
+ if (!smartlist_strings_eq(old_options->TrackHostExits,
+ options->TrackHostExits))
+ revise_trackexithosts = 1;
+
+ if (revise_trackexithosts)
addressmap_clear_excluded_trackexithosts(options);
+
+ if (old_options->AutomapHostsOnResolve && !options->AutomapHostsOnResolve) {
+ revise_automap_entries = 1;
+ } else if (options->AutomapHostsOnResolve) {
+ if (!smartlist_strings_eq(old_options->AutomapHostsSuffixes,
+ options->AutomapHostsSuffixes))
+ revise_automap_entries = 1;
+ else if (!opt_streq(old_options->VirtualAddrNetwork,
+ options->VirtualAddrNetwork))
+ revise_automap_entries = 1;
}
+ if (revise_automap_entries)
+ addressmap_clear_invalid_automaps(options);
+
/* How long should we delay counting bridge stats after becoming a bridge?
* We use this so we don't count people who used our bridge thinking it is
* a relay. If you change this, don't forget to change the log message
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 186137b1d..ec3b41744 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -810,7 +810,8 @@ clear_trackexithost_mappings(const char *exitname)
}
/** Remove all TRACKEXIT mappings from the addressmap for which the target
- * host is unknown or no longer allowed. */
+ * host is unknown or no longer allowed, or for which the source address
+ * is no longer in trackexithosts. */
void
addressmap_clear_excluded_trackexithosts(or_options_t *options)
{
@@ -851,7 +852,8 @@ addressmap_clear_excluded_trackexithosts(or_options_t *options)
tor_free(nodename);
if (!node ||
(allow_nodes && !routerset_contains_node(allow_nodes, node)) ||
- routerset_contains_node(exclude_nodes, node)) {
+ routerset_contains_node(exclude_nodes, node) ||
+ !hostname_in_track_host_exits(options, address)) {
/* We don't know this one, or we want to be rid of it. */
addressmap_ent_remove(address, ent);
MAP_DEL_CURRENT(address);
@@ -859,6 +861,49 @@ addressmap_clear_excluded_trackexithosts(or_options_t *options)
} STRMAP_FOREACH_END;
}
+/** Remove all AUTOMAP mappings from the addressmap for which the
+ * source address no longer matches AutomapHostsSuffixes, which is
+ * no longer allowed by AutomapHostsOnResolve, or for which the
+ * target address is no longer in the virtual network. */
+void
+addressmap_clear_invalid_automaps(or_options_t *options)
+{
+ int clear_all = !options->AutomapHostsOnResolve;
+ const smartlist_t *suffixes = options->AutomapHostsSuffixes;
+
+ if (!addressmap)
+ return;
+
+ if (!suffixes)
+ clear_all = 1; /* This should be impossible, but let's be sure. */
+
+ STRMAP_FOREACH_MODIFY(addressmap, src_address, addressmap_entry_t *, ent) {
+ int remove = clear_all;
+ if (ent->source != ADDRMAPSRC_AUTOMAP)
+ continue; /* not an automap mapping. */
+
+ if (!remove) {
+ int suffix_found = 0;
+ SMARTLIST_FOREACH(suffixes, const char *, suffix, {
+ if (!strcasecmpend(src_address, suffix)) {
+ suffix_found = 1;
+ break;
+ }
+ });
+ if (!suffix_found)
+ remove = 1;
+ }
+
+ if (!remove && ! address_is_in_virtual_range(ent->new_address))
+ remove = 1;
+
+ if (remove) {
+ addressmap_ent_remove(src_address, ent);
+ MAP_DEL_CURRENT(src_address);
+ }
+ } STRMAP_FOREACH_END;
+}
+
/** Remove all entries from the addressmap that were set via the
* configuration file or the command line. */
void
@@ -1370,7 +1415,7 @@ addressmap_register_virtual_address(int type, char *new_address)
log_info(LD_APP, "Registering map from %s to %s", *addrp, new_address);
if (vent_needs_to_be_added)
strmap_set(virtaddress_reversemap, new_address, vent);
- addressmap_register(*addrp, new_address, 2, ADDRMAPSRC_CONTROLLER);
+ addressmap_register(*addrp, new_address, 2, ADDRMAPSRC_AUTOMAP);
#if 0
{
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index 562db5b68..11b25f0c8 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -64,6 +64,7 @@ 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_clear_invalid_automaps(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/main.c b/src/or/main.c
index d5ce6ee48..389ddbdf1 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1639,7 +1639,6 @@ do_hup(void)
router_reset_warnings();
routerlist_reset_warnings();
- addressmap_clear_transient();
/* first, reload config variables, in case they've changed */
if (options->ReloadTorrcOnSIGHUP) {
/* no need to provide argc/v, they've been cached in init_from_config */
diff --git a/src/or/or.h b/src/or/or.h
index 74b02444e..c66271956 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3335,6 +3335,9 @@ typedef enum setopt_err_t {
typedef enum {
/** We're remapping this address because the controller told us to. */
ADDRMAPSRC_CONTROLLER,
+ /** We're remapping this address because of an AutomapHostsOnResolve
+ * configuration. */
+ ADDRMAPSRC_AUTOMAP,
/** We're remapping this address because our configuration (via torrc, the
* command line, or a SETCONF command) told us to. */
ADDRMAPSRC_TORRC,