diff options
author | Roger Dingledine <arma@torproject.org> | 2003-12-03 10:28:51 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2003-12-03 10:28:51 +0000 |
commit | 63f81bddae0e5b80d2702ee7780346d03bdad84f (patch) | |
tree | 1ee4c70553f9c84619ed4482c49717d383c14e76 /src | |
parent | 99db996aeff89448dd3adac8c525c6e134d64301 (diff) | |
download | tor-63f81bddae0e5b80d2702ee7780346d03bdad84f.tar tor-63f81bddae0e5b80d2702ee7780346d03bdad84f.tar.gz |
pick nodes for a circuit only from those the directory says are up
svn:r880
Diffstat (limited to 'src')
-rw-r--r-- | src/or/onion.c | 26 | ||||
-rw-r--r-- | src/or/or.h | 3 | ||||
-rw-r--r-- | src/or/routers.c | 31 |
3 files changed, 48 insertions, 12 deletions
diff --git a/src/or/onion.c b/src/or/onion.c index 0e5a5d5c0..0f67d37eb 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -439,20 +439,14 @@ int onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t *state, rout { int cur_len; crypt_path_t *cpath, *hop; - routerinfo_t **rarray, *r; + routerinfo_t *r; routerinfo_t *choice; - int rarray_len; int i; - directory_t *dir; int n_failures; assert(head_ptr); assert(router_out); - router_get_directory(&dir); - rarray = dir->routers; - rarray_len = dir->n_routers; - if (!*head_ptr) { cur_len = 0; } else { @@ -486,14 +480,26 @@ int onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t *state, rout /* XXX through each of these, don't pick nodes that are down */ if(cur_len == 0) { /* picking entry node */ log_fn(LOG_DEBUG, "Contemplating first hop: random choice."); - choice = rarray[crypto_pseudo_rand_int(rarray_len)]; + choice = router_pick_randomly_from_running(); + if(!choice) { + log_fn(LOG_WARN,"No routers are running while picking entry node. Failing."); + return -1; + } } else if (cur_len == state->desired_path_len - 1) { /* Picking last node */ log_fn(LOG_DEBUG, "Contemplating last hop: choice already made."); choice = router_get_by_nickname(state->chosen_exit); - /* XXX check if null */ + if(!choice) { + log_fn(LOG_WARN,"Our chosen exit %s is no longer in the directory? Failing.", + state->chosen_exit); + return -1; + } } else { log_fn(LOG_DEBUG, "Contemplating intermediate hop: random choice."); - choice = rarray[crypto_pseudo_rand_int(rarray_len)]; + choice = router_pick_randomly_from_running(); + if(!choice) { + log_fn(LOG_WARN,"No routers are running while picking intermediate node. Failing."); + return -1; + } } log_fn(LOG_DEBUG,"Contemplating router %s for hop %d (exit is %s)", choice->nickname, cur_len, state->chosen_exit); diff --git a/src/or/or.h b/src/or/or.h index 37c51c3be..6d7500720 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -730,15 +730,14 @@ cpath_build_state_t *onion_new_cpath_build_state(void); /********************************* routers.c ***************************/ -int learn_my_address(struct sockaddr_in *me); void router_retry_connections(void); routerinfo_t *router_pick_directory_server(void); +routerinfo_t *router_pick_randomly_from_running(void); void router_upload_desc_to_dirservers(void); routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port); routerinfo_t *router_get_by_link_pk(crypto_pk_env_t *pk); routerinfo_t *router_get_by_nickname(char *nickname); void router_get_directory(directory_t **pdirectory); -int router_is_me(uint32_t addr, uint16_t port); void router_mark_as_down(char *nickname); int router_get_list_from_file(char *routerfile); int router_get_router_hash(char *s, char *digest); diff --git a/src/or/routers.c b/src/or/routers.c index 6405446f5..6d159016c 100644 --- a/src/or/routers.c +++ b/src/or/routers.c @@ -77,6 +77,37 @@ routerinfo_t *router_pick_directory_server(void) { return dirserver; } +routerinfo_t *router_pick_randomly_from_running(void) { + int i,j; + int num_running=0; + + if(!directory) + return NULL; + + for(i=0;i<directory->n_routers;i++) { + if(directory->routers[i]->is_running) + num_running++; + } + + if(!num_running) { + log_fn(LOG_INFO,"No routers are running. Returning NULL."); + return NULL; + } + j = crypto_pseudo_rand_int(num_running); + for (i=0;i<directory->n_routers;i++) { + if (directory->routers[i]->is_running) { + if (j) + --j; + else { + log_fn(LOG_DEBUG, "Chose server '%s'", directory->routers[i]->nickname); + return directory->routers[i]; + } + } + } + assert(0); + return NULL; +} + void router_upload_desc_to_dirservers(void) { int i; routerinfo_t *router; |