From 0e5abcb6359693b4798144be7628554596aef72a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 19 Nov 2003 01:24:19 +0000 Subject: [PATCH] Skip non-running routers for exit node selection svn:r842 --- src/or/onion.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/or/onion.c b/src/or/onion.c index 907bd6606f..20a1f36607 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -234,6 +234,7 @@ static routerinfo_t *choose_good_exit_server(directory_t *dir) int best_support_idx = -1; int best_maybe_support_idx = -1; int n_best_support=0, n_best_maybe_support=0; + int n_running_routers=0; get_connection_array(&carray, &n_connections); @@ -257,8 +258,11 @@ static routerinfo_t *choose_good_exit_server(directory_t *dir) n_maybe_supported = tor_malloc(sizeof(int)*dir->n_routers); for (i = 0; i < dir->n_routers; ++i) { /* iterate over routers */ n_supported[i] = n_maybe_supported[i] = 0; - if(!dir->routers[i]->is_running) + if(!dir->routers[i]->is_running) { + n_supported[i] = n_maybe_supported[i] = -1; continue; /* skip routers which are known to be down */ + } + ++n_running_routers; for (j = 0; j < n_connections; ++j) { /* iterate over connections */ if (carray[j]->type != CONN_TYPE_AP || carray[j]->state == AP_CONN_STATE_CIRCUIT_WAIT || @@ -297,7 +301,7 @@ static routerinfo_t *choose_good_exit_server(directory_t *dir) n_best_maybe_support, best_maybe_support, n_pending_connections); /* If any routers definitely support any pending connections, choose one * at random. */ - if (best_support) { + if (best_support > 0) { i = crypto_pseudo_rand_int(n_best_support); /* Iterate over the routers, until we find the i-th one such that * n_supported[j] == best_support @@ -317,7 +321,7 @@ static routerinfo_t *choose_good_exit_server(directory_t *dir) } /* If any routers _maybe_ support pending connections, choose one at * random, as above. */ - if (best_maybe_support) { + if (best_maybe_support > 0) { i = crypto_pseudo_rand_int(n_best_maybe_support); for (j = best_maybe_support_idx; j < dir->n_routers; ++j) { if (n_maybe_supported[j] == best_maybe_support) { @@ -334,9 +338,23 @@ static routerinfo_t *choose_good_exit_server(directory_t *dir) } /* Either there are no pending connections, or no routers even seem to * possibly support any of them. Choose a router at random. */ - /* XXX should change to not choose non-running routers */ tor_free(n_supported); tor_free(n_maybe_supported); - i = crypto_pseudo_rand_int(dir->n_routers); + if (!n_running_routers) { + log_fn(LOG_WARN, "No routers seem to be running; can't choose an exit."); + return NULL; + } + i = crypto_pseudo_rand_int(n_running_routers); + /* Iterate over the routers, till we find the i'th one that has ->is_running + */ + for (j = 0; j < dir->n_routers; ++j) { + if (dir->routers[j]->is_running) { + if (i) { + --i; + } else { + return dir->routers[j]; + } + } + } log_fn(LOG_DEBUG, "Chose exit server '%s'", dir->routers[i]->nickname); return dir->routers[i]; } -- 2.11.4.GIT