Merge branch 'bug1345' into maint-0.2.2

This commit is contained in:
Nick Mathewson 2011-05-15 11:40:14 -04:00
commit a5d40c2d0f
10 changed files with 138 additions and 20 deletions

13
changes/bug1345 Normal file
View File

@ -0,0 +1,13 @@
o Minor bugfixes:
- On SIGHUP, do not clear out all TrackHostExits mappings, client DNS
cache entries, and virtual address mappings: that's what NEWNYM is
for. Bugfix on Tor 0.1.0.1-rc; fixes bug 1345.
- When TrackHostExits is changed from a controller, remove any
mappings for hosts that should no longer have their exits tracked.
Bugfix on Tor 0.1.0.1-rc.
- When VirtualAddrNetwork option is changed from a controller,
remove any mappings for hosts that were automapped to
that network. Bugfix on 0.1.1.19-rc.
- When one of the AutomapHosts* options is changed from a
controller, remove any mappings for hosts that should no longer be
automapped. Bugfix on 0.2.0.1-alpha.

View File

@ -215,6 +215,25 @@ smartlist_string_num_isin(const smartlist_t *sl, int num)
return smartlist_string_isin(sl, buf); 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 /** Return true iff <b>sl</b> has some element E such that
* tor_memeq(E,<b>element</b>,DIGEST_LEN) * tor_memeq(E,<b>element</b>,DIGEST_LEN)
*/ */

View File

@ -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) int smartlist_string_isin_case(const smartlist_t *sl, const char *element)
ATTR_PURE; ATTR_PURE;
int smartlist_string_num_isin(const smartlist_t *sl, int num) 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) int smartlist_digest_isin(const smartlist_t *sl, const char *element)
ATTR_PURE; ATTR_PURE;
int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2) int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2)

View File

@ -1485,12 +1485,33 @@ link_apconn_to_circ(edge_connection_t *apconn, origin_circuit_t *circ,
} }
} }
/** If an exit wasn't specifically chosen, save the history for future /** Return true iff <b>address</b> is matched by one of the entries in
* use. */ * 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 static void
consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ) consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
{ {
int found_needle = 0;
or_options_t *options = get_options(); or_options_t *options = get_options();
size_t len; size_t len;
char *new_address; char *new_address;
@ -1503,18 +1524,8 @@ consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
options->TrackHostExitsExpire)) options->TrackHostExitsExpire))
return; /* nothing to track, or already mapped */ return; /* nothing to track, or already mapped */
SMARTLIST_FOREACH(options->TrackHostExits, const char *, cp, { if (!hostname_in_track_host_exits(options, conn->socks_request->address) ||
if (cp[0] == '.') { /* match end */ !circ->build_state->chosen_exit)
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)
return; return;
/* write down the fingerprint of the chosen exit, not the nickname, /* write down the fingerprint of the chosen exit, not the nickname,

View File

@ -51,5 +51,7 @@ int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
crypt_path_t *cpath); crypt_path_t *cpath);
int connection_ap_handshake_attach_circuit(edge_connection_t *conn); int connection_ap_handshake_attach_circuit(edge_connection_t *conn);
int hostname_in_track_host_exits(or_options_t *options, const char *address);
#endif #endif

View File

@ -1264,6 +1264,8 @@ options_act(or_options_t *old_options)
/* Check for transitions that need action. */ /* Check for transitions that need action. */
if (old_options) { if (old_options) {
int revise_trackexithosts = 0;
int revise_automap_entries = 0;
if ((options->UseEntryGuards && !old_options->UseEntryGuards) || if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
!routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes) || !routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes) ||
!routerset_equal(old_options->ExcludeExitNodes, !routerset_equal(old_options->ExcludeExitNodes,
@ -1276,9 +1278,30 @@ options_act(or_options_t *old_options)
"excluded node lists. Abandoning previous circuits."); "excluded node lists. Abandoning previous circuits.");
circuit_mark_all_unused_circs(); circuit_mark_all_unused_circs();
circuit_expire_all_dirty_circs(); circuit_expire_all_dirty_circs();
addressmap_clear_excluded_trackexithosts(options); 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? /* 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 * 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 * a relay. If you change this, don't forget to change the log message

View File

@ -810,7 +810,8 @@ clear_trackexithost_mappings(const char *exitname)
} }
/** Remove all TRACKEXIT mappings from the addressmap for which the target /** 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 void
addressmap_clear_excluded_trackexithosts(or_options_t *options) addressmap_clear_excluded_trackexithosts(or_options_t *options)
{ {
@ -851,7 +852,8 @@ addressmap_clear_excluded_trackexithosts(or_options_t *options)
tor_free(nodename); tor_free(nodename);
if (!ri || if (!ri ||
(allow_nodes && !routerset_contains_router(allow_nodes, ri)) || (allow_nodes && !routerset_contains_router(allow_nodes, ri)) ||
routerset_contains_router(exclude_nodes, ri)) { routerset_contains_router(exclude_nodes, ri) ||
!hostname_in_track_host_exits(options, address)) {
/* We don't know this one, or we want to be rid of it. */ /* We don't know this one, or we want to be rid of it. */
addressmap_ent_remove(address, ent); addressmap_ent_remove(address, ent);
MAP_DEL_CURRENT(address); MAP_DEL_CURRENT(address);
@ -859,6 +861,49 @@ addressmap_clear_excluded_trackexithosts(or_options_t *options)
} STRMAP_FOREACH_END; } 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 /** Remove all entries from the addressmap that were set via the
* configuration file or the command line. */ * configuration file or the command line. */
void 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); log_info(LD_APP, "Registering map from %s to %s", *addrp, new_address);
if (vent_needs_to_be_added) if (vent_needs_to_be_added)
strmap_set(virtaddress_reversemap, new_address, vent); 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 #if 0
{ {

View File

@ -62,6 +62,7 @@ int address_is_invalid_destination(const char *address, int client);
void addressmap_init(void); void addressmap_init(void);
void addressmap_clear_excluded_trackexithosts(or_options_t *options); 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_clean(time_t now);
void addressmap_clear_configured(void); void addressmap_clear_configured(void);
void addressmap_clear_transient(void); void addressmap_clear_transient(void);

View File

@ -1417,7 +1417,6 @@ do_hup(void)
router_reset_warnings(); router_reset_warnings();
routerlist_reset_warnings(); routerlist_reset_warnings();
addressmap_clear_transient();
/* first, reload config variables, in case they've changed */ /* first, reload config variables, in case they've changed */
if (options->ReloadTorrcOnSIGHUP) { if (options->ReloadTorrcOnSIGHUP) {
/* no need to provide argc/v, they've been cached in init_from_config */ /* no need to provide argc/v, they've been cached in init_from_config */

View File

@ -3150,6 +3150,9 @@ typedef enum setopt_err_t {
typedef enum { typedef enum {
/** We're remapping this address because the controller told us to. */ /** We're remapping this address because the controller told us to. */
ADDRMAPSRC_CONTROLLER, 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 /** We're remapping this address because our configuration (via torrc, the
* command line, or a SETCONF command) told us to. */ * command line, or a SETCONF command) told us to. */
ADDRMAPSRC_TORRC, ADDRMAPSRC_TORRC,