aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--src/common/container.c14
-rw-r--r--src/common/container.h2
-rw-r--r--src/or/circuitbuild.c76
-rw-r--r--src/or/or.h3
-rw-r--r--src/or/routerlist.c38
6 files changed, 84 insertions, 55 deletions
diff --git a/ChangeLog b/ChangeLog
index a39c1ad15..c3dbeab32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;
}