diff --git a/src/or/or.h b/src/or/or.h index 98971dcadf..cf16c22e6a 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -798,6 +798,8 @@ int router_is_me(uint32_t addr, uint16_t port); void router_forget_router(uint32_t addr, uint16_t port); int router_get_list_from_file(char *routerfile); int router_resolve(routerinfo_t *router); +int router_resolve_directory(directory_t *dir); + /* Reads a list of known routers, unsigned. */ int router_get_list_from_string(char *s); /* Exported for debugging */ diff --git a/src/or/routers.c b/src/or/routers.c index e3f5bc2110..11156dcecd 100644 --- a/src/or/routers.c +++ b/src/or/routers.c @@ -518,7 +518,10 @@ static char *find_whitespace(char *s) { int router_get_list_from_string(char *s) { - return router_get_list_from_string_impl(s, &directory); + int i; + i = router_get_list_from_string_impl(s, &directory); + router_resolve_directory(directory); + return i; } int router_get_list_from_string_impl(char *s, directory_t **dest) { @@ -548,7 +551,10 @@ static int router_get_dir_hash(char *s, char *digest) int router_get_dir_from_string(char *s, crypto_pk_env_t *pkey) { - return router_get_dir_from_string_impl(s, &directory, pkey); + int i; + i = router_get_dir_from_string_impl(s, &directory, pkey); + router_resolve_directory(directory); + return i; } int router_get_dir_from_string_impl(char *s, directory_t **dest, @@ -678,6 +684,28 @@ router_resolve(routerinfo_t *router) return 0; } +int +router_resolve_directory(directory_t *dir) +{ + int i, max; + if (!dir) + dir = directory; + + max = dir->n_routers; + for (i = 0; i < max; ++i) { + if (router_resolve(dir->routers[i])) { + /* ARMA: Is this the right way to remove a router from the directory? */ + dir->routers[i]->next = NULL; + routerlist_free(dir->routers[i]); + dir->routers[i] = dir->routers[--max]; + dir->routers[max] = NULL; + --dir->n_routers; + } + } + + return 0; +} + routerinfo_t *router_get_entry_from_string(char **s) { directory_token_t tok;