diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/common/container.c | 14 | ||||
-rw-r--r-- | src/common/container.h | 2 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 76 | ||||
-rw-r--r-- | src/or/or.h | 3 | ||||
-rw-r--r-- | src/or/routerlist.c | 38 |
6 files changed, 84 insertions, 55 deletions
@@ -34,6 +34,9 @@ Changes in version 0.1.2.8-alpha - 2007-??-?? other than file-not-found. - Don't warn the user when cached-routers.new doesn't exist: that's perfectly fine when starting up for the first time. + - When EntryNodes are configured, rebuild the guard list to contain, in + order: the EntryNodes that were guards before; the rest of the + EntryNodes; the nodes that were guards before. o Minor features: - Warn the user when an application uses the obsolete binary v0 @@ -52,6 +55,9 @@ Changes in version 0.1.2.8-alpha - 2007-??-?? which are incoming connections and which are outgoing. - Discard any v1 directory info that's over 1 month old (for directories) or over 1 week old (for running-routers lists). + - Do not warn when individual nodes in the configuration's EntryNodes, + ExitNodes (etc) are down: warn only when all possible nodes are down. + (Fixes bug 348.) Changes in version 0.1.2.7-alpha - 2007-02-06 diff --git a/src/common/container.c b/src/common/container.c index f5461ef4c..5f829c29e 100644 --- a/src/common/container.c +++ b/src/common/container.c @@ -221,6 +221,20 @@ smartlist_string_num_isin(const smartlist_t *sl, int num) return smartlist_string_isin(sl, buf); } +/** Return true iff <b>sl</b> has some element E such that + * !memcmp(E,<b>element</b>,DIGEST_LEN) + */ +int +smartlist_digest_isin(const smartlist_t *sl, const char *element) +{ + int i; + if (!sl) return 0; + for (i=0; i < sl->num_used; i++) + if (memcmp((const char*)sl->list[i],element,DIGEST_LEN)==0) + return 1; + return 0; +} + /** Return true iff some element E of sl2 has smartlist_isin(sl1,E). */ int diff --git a/src/common/container.h b/src/common/container.h index 236b01164..ff2d3cb01 100644 --- a/src/common/container.h +++ b/src/common/container.h @@ -43,6 +43,8 @@ int smartlist_string_isin(const smartlist_t *sl, const char *element) 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_digest_isin(const smartlist_t *sl, const char *element) + ATTR_PURE; int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2) ATTR_PURE; void smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2); diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index a15b2b925..ac76c6fea 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1226,10 +1226,10 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime, n_pending_connections); preferredexits = smartlist_create(); - add_nickname_list_to_smartlist(preferredexits,options->ExitNodes,1,1,1); + add_nickname_list_to_smartlist(preferredexits,options->ExitNodes,1); excludedexits = smartlist_create(); - add_nickname_list_to_smartlist(excludedexits,options->ExcludeNodes,0,0,1); + add_nickname_list_to_smartlist(excludedexits,options->ExcludeNodes,0); sl = smartlist_create(); @@ -2253,46 +2253,58 @@ entry_nodes_should_be_added(void) void entry_guards_prepend_from_config(void) { - int missed_some = 0; - int idx; or_options_t *options = get_options(); - smartlist_t *routers = smartlist_create(); - smartlist_t *tmp = smartlist_create(); + smartlist_t *entry_routers = smartlist_create(); + smartlist_t *old_entry_guards_on_list = smartlist_create(); + smartlist_t *old_entry_guards_not_on_list = smartlist_create(); + smartlist_t *entry_fps = smartlist_create(); tor_assert(entry_guards); tor_assert(options->EntryNodes); - if (options->StrictEntryNodes) { - log_info(LD_CIRC,"Clearing old entry guards"); - SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e, tor_free(e)); - smartlist_clear(entry_guards); - entry_guards_changed(); - } - - add_nickname_list_to_smartlist(routers, options->EntryNodes, - 0, 1, 1); - - /* take a moment first to notice whether we got them all */ log_info(LD_CIRC,"Adding configured EntryNodes '%s'.", options->EntryNodes); - smartlist_split_string(tmp, options->EntryNodes, ",", - SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); - missed_some = smartlist_len(routers) != smartlist_len(tmp); - SMARTLIST_FOREACH(tmp, char *, nick, tor_free(nick)); - smartlist_free(tmp); - for (idx = smartlist_len(routers)-1 ; idx >= 0; idx--) { - /* pick off the last one, turn it into a router, prepend it - * to our entry_guards list. If we can't find it, set missed_some - * to 1. */ - routerinfo_t *r = smartlist_get(routers, idx); - add_an_entry_guard(r); + /* Split entry guards into those on the list and those not. */ + add_nickname_list_to_smartlist(entry_routers, options->EntryNodes, 0); + SMARTLIST_FOREACH(entry_routers, routerinfo_t *, ri, + smartlist_add(entry_fps,ri->cache_info.identity_digest)); + SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e, { + if (smartlist_digest_isin(entry_fps, e->identity)) + smartlist_add(old_entry_guards_on_list, e); + else + smartlist_add(old_entry_guards_not_on_list, e); + }); + + /* Remove all currently configured entry guards from entry_routers. */ + SMARTLIST_FOREACH(entry_routers, routerinfo_t *, ri, { + if (is_an_entry_guard(ri->cache_info.identity_digest)) { + smartlist_del(entry_routers, ri_sl_idx--); + } + }); + + /* Now build the new entry_guards list. */ + smartlist_clear(entry_guards); + /* First, the previously configured guards that are in EntryNodes. */ + smartlist_add_all(entry_guards, old_entry_guards_on_list); + /* Next, the rest of EntryNodes */ + SMARTLIST_FOREACH(entry_routers, routerinfo_t *, ri, { + add_an_entry_guard(ri); + }); + /* Finally, the remaining EntryNodes, unless we're strict */ + if (options->StrictEntryNodes) { + SMARTLIST_FOREACH(old_entry_guards_not_on_list, entry_guard_t *, e, + tor_free(e)); + } else { + smartlist_add_all(entry_guards, old_entry_guards_not_on_list); } - if (!missed_some) - should_add_entry_nodes = 0; /* whew, we're done */ - - smartlist_free(routers); + should_add_entry_nodes = 0; + smartlist_free(entry_routers); + smartlist_free(entry_fps); + smartlist_free(old_entry_guards_on_list); + smartlist_free(old_entry_guards_not_on_list); + entry_guards_changed(); } /** Pick a live (up and listed) entry guard from entry_guards, and diff --git a/src/or/or.h b/src/or/or.h index b68ac432b..6ca830ad3 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2869,8 +2869,7 @@ trusted_dir_server_t *router_get_trusteddirserver_by_digest( const char *digest); void routerlist_add_family(smartlist_t *sl, routerinfo_t *router); void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list, - int must_be_running, - int warn_if_down, int warn_if_unnamed); + int must_be_running); int router_nickname_is_in_list(routerinfo_t *router, const char *list); routerinfo_t *routerlist_find_my_routerinfo(void); routerinfo_t *router_find_exact_exit_enclave(const char *address, diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 023a9c226..1de2607f1 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -751,7 +751,7 @@ routerlist_add_family(smartlist_t *sl, routerinfo_t *router) /* If the user declared any families locally, honor those too. */ for (cl = get_options()->NodeFamilies; cl; cl = cl->next) { if (router_nickname_is_in_list(router, cl->value)) { - add_nickname_list_to_smartlist(sl, cl->value, 0, 1, 1); + add_nickname_list_to_smartlist(sl, cl->value, 0); } } } @@ -759,14 +759,12 @@ routerlist_add_family(smartlist_t *sl, routerinfo_t *router) /** Given a (possibly NULL) comma-and-whitespace separated list of nicknames, * see which nicknames in <b>list</b> name routers in our routerlist, and add * the routerinfos for those routers to <b>sl</b>. If <b>must_be_running</b>, - * only include routers that we think are running. If <b>warn_if_down</b>, - * warn if some included routers aren't running. If <b>warn_if_unnamed</b>, - * warn if any non-Named routers are specified by nickname. + * only include routers that we think are running. + * Warn if any non-Named routers are specified by nickname. */ void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list, - int must_be_running, - int warn_if_down, int warn_if_unnamed) + int must_be_running) { routerinfo_t *router; smartlist_t *nickname_list; @@ -789,21 +787,13 @@ add_nickname_list_to_smartlist(smartlist_t *sl, const char *list, log_warn(LD_CONFIG, "Nickname '%s' is misformed; skipping", nick); continue; } - router = router_get_by_nickname(nick, warn_if_unnamed); + router = router_get_by_nickname(nick, 1); warned = smartlist_string_isin(warned_nicknames, nick); if (router) { if (!must_be_running || router->is_running) { smartlist_add(sl,router); - if (warned) - smartlist_string_remove(warned_nicknames, nick); - } else { - if (!warned) { - log_fn(warn_if_down ? LOG_WARN : LOG_DEBUG, LD_CONFIG, - "Nickname list includes '%s' which is known but down.",nick); - smartlist_add(warned_nicknames, tor_strdup(nick)); - } } - } else if (!router_get_combined_status_by_nickname(nick,warn_if_unnamed)) { + } else if (!router_get_combined_status_by_nickname(nick,1)) { if (!warned) { log_fn(have_dir_info ? LOG_WARN : LOG_INFO, LD_CONFIG, "Nickname list includes '%s' which isn't a known router.",nick); @@ -1135,13 +1125,13 @@ router_choose_random_node(const char *preferred, routerinfo_t *choice = NULL; excludednodes = smartlist_create(); - add_nickname_list_to_smartlist(excludednodes,excluded,0,0,1); + add_nickname_list_to_smartlist(excludednodes,excluded,0); /* Try the preferred nodes first. Ignore need_uptime and need_capacity * and need_guard, since the user explicitly asked for these nodes. */ if (preferred) { sl = smartlist_create(); - add_nickname_list_to_smartlist(sl,preferred,1,1,1); + add_nickname_list_to_smartlist(sl,preferred,1); smartlist_subtract(sl,excludednodes); if (excludedsmartlist) smartlist_subtract(sl,excludedsmartlist); @@ -1179,9 +1169,15 @@ router_choose_random_node(const char *preferred, } } smartlist_free(excludednodes); - if (!choice) - log_warn(LD_CIRC, - "No available nodes when trying to choose node. Failing."); + if (!choice) { + if (strict) { + log_warn(LD_CIRC, "All preferred nodes were down when trying to choose " + "node, and the Strict[...]Nodes option was set. Failing."); + } else { + log_warn(LD_CIRC, + "No available nodes when trying to choose node. Failing."); + } + } return choice; } |