diff options
author | Roger Dingledine <arma@torproject.org> | 2004-07-20 06:44:16 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2004-07-20 06:44:16 +0000 |
commit | f54224ab356eda91f3488ce454617c984caa0b17 (patch) | |
tree | 1b5ea4478e2b218bec7a6e7bb4522e01f9463638 /src | |
parent | b4d4a961b114392b9b09b98951e0a36778aba1e1 (diff) | |
download | tor-f54224ab356eda91f3488ce454617c984caa0b17.tar tor-f54224ab356eda91f3488ce454617c984caa0b17.tar.gz |
clients can now pick non-authdirservers for fetching directories.
servers still pick authdirservers, but they never pick themselves.
but picking themselves for fetching rend descs is ok.
svn:r2059
Diffstat (limited to 'src')
-rw-r--r-- | src/or/directory.c | 42 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/routerlist.c | 90 |
3 files changed, 81 insertions, 53 deletions
diff --git a/src/or/directory.c b/src/or/directory.c index 2bb27b1e7..d6c9da3b1 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -80,11 +80,27 @@ void directory_get_from_dirserver(uint8_t purpose, const char *payload, int payload_len) { - /* FFFF we might pass pick_directory_server a boolean to prefer - * picking myself for some purposes, or prefer picking not myself - * for other purposes. */ - directory_initiate_command(router_pick_directory_server(), - purpose, payload, payload_len); + routerinfo_t *ds; + + if (purpose == DIR_PURPOSE_FETCH_DIR) { + if (server_mode()) { + /* only ask authdirservers, don't ask myself */ + ds = router_pick_directory_server(1, 1); + } else { + /* anybody with a non-zero dirport will do */ + ds = router_pick_directory_server(0, 1); + } + } else { // (purpose == DIR_PURPOSE_FETCH_RENDDESC) + /* only ask authdirservers, any of them will do */ + ds = router_pick_directory_server(1, 0); + } + + if (!ds) { /* no viable dirserver found */ + log_fn(LOG_WARN,"No running dirservers known. Not trying. (purpose %d)", purpose); + return; + } + + directory_initiate_command(ds, purpose, payload, payload_len); } /** Launch a new connection to the directory server <b>router</b> to upload or @@ -102,6 +118,9 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, { connection_t *conn; + tor_assert(router); + tor_assert(router->dir_port); + switch (purpose) { case DIR_PURPOSE_FETCH_DIR: @@ -121,13 +140,6 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, tor_assert(0); } - if (!router) { /* i guess they didn't have one in mind for me to use */ - log_fn(LOG_WARN,"No running dirservers known. Not trying. (purpose %d)", purpose); - return; - } - - tor_assert(router->dir_port); - conn = connection_new(CONN_TYPE_DIR); /* set up conn so it's got all the data we need to remember */ @@ -169,7 +181,7 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, } } else { /* we want to connect via tor */ /* make an AP connection - * populate it and add it at the right state + * populate it and add it at the right state * socketpair and hook up both sides */ conn->s = connection_ap_make_bridge(conn->address, conn->port); @@ -297,7 +309,7 @@ parse_http_response(char *headers, int *code, char **message) * will take care of marking the connection for close. */ static int -connection_dir_client_finished_reading(connection_t *conn) +connection_dir_client_reached_eof(connection_t *conn) { char *body; char *headers; @@ -445,7 +457,7 @@ int connection_dir_process_inbuf(connection_t *conn) { return -1; } - retval = connection_dir_client_finished_reading(conn); + retval = connection_dir_client_reached_eof(conn); connection_mark_for_close(conn); return retval; } /* endif 'reached eof' */ diff --git a/src/or/or.h b/src/or/or.h index a5bbe6319..a54e21837 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1355,7 +1355,7 @@ int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router, /********************************* routerlist.c ***************************/ -routerinfo_t *router_pick_directory_server(void); +routerinfo_t *router_pick_directory_server(int requireauth, int requireothers); int all_directory_servers_down(void); struct smartlist_t; void add_nickname_list_to_smartlist(struct smartlist_t *sl, const char *list); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 282572d8f..2ecb1aaab 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -19,7 +19,9 @@ extern or_options_t options; /**< command-line and config-file options */ /* ********************************************************************** */ /* static function prototypes */ -static routerinfo_t *router_pick_directory_server_impl(void); +static routerinfo_t * +router_pick_directory_server_impl(int requireauth, int preferothers); +static void mark_all_authdirservers_up(void); static int router_resolve_routerlist(routerlist_t *dir); /****************************************************************************/ @@ -35,32 +37,46 @@ static routerlist_t *routerlist = NULL; extern int has_fetched_directory; /**< from main.c */ -/** Try to find a running dirserver. If there are no running dirservers - * in our routerlist, reload the routerlist and try again. */ -routerinfo_t *router_pick_directory_server(void) { +/** Try to find a running dirserver. If there are no running dirservers + * in our routerlist, set all the authoritative ones as running again, + * and pick one. If there are no dirservers at all in our routerlist, + * reload the routerlist and try one last time. */ +routerinfo_t *router_pick_directory_server(int requireauth, int requireothers) { routerinfo_t *choice; - choice = router_pick_directory_server_impl(); - if(!choice) { - log_fn(LOG_WARN,"No dirservers known. Reloading and trying again."); - has_fetched_directory=0; /* reset it */ - routerlist_clear_trusted_directories(); - if(options.RouterFile) { - if(router_load_routerlist_from_file(options.RouterFile, 1) < 0) - return NULL; - } else { - if(config_assign_default_dirservers() < 0) - return NULL; - } - /* give it another try */ - choice = router_pick_directory_server_impl(); + choice = router_pick_directory_server_impl(requireauth, requireothers); + if(choice) + return choice; + + log_fn(LOG_INFO,"No dirservers are reachable. Trying them all again."); + /* mark all authdirservers are up again */ + mark_all_authdirservers_up(); + /* try again */ + choice = router_pick_directory_server_impl(requireauth, requireothers); + if(choice) + return choice; + + log_fn(LOG_WARN,"No dirservers known. Reloading and trying again."); + has_fetched_directory=0; /* reset it */ + routerlist_clear_trusted_directories(); + if(options.RouterFile) { + if(router_load_routerlist_from_file(options.RouterFile, 1) < 0) + return NULL; + } else { + if(config_assign_default_dirservers() < 0) + return NULL; } + /* give it one last try */ + choice = router_pick_directory_server_impl(requireauth, requireothers); return choice; } -/** Pick a random running router that's a trusted dirserver from our - * routerlist. */ -static routerinfo_t *router_pick_directory_server_impl(void) { +/** Pick a random running router from our routerlist. If requireauth, + * it has to be a trusted server. If requireothers, it cannot be us. + */ +static routerinfo_t * +router_pick_directory_server_impl(int requireauth, int requireothers) +{ int i; routerinfo_t *router; smartlist_t *sl; @@ -72,36 +88,36 @@ static routerinfo_t *router_pick_directory_server_impl(void) { sl = smartlist_create(); for(i=0;i< smartlist_len(routerlist->routers); i++) { router = smartlist_get(routerlist->routers, i); - if(router->is_running && router->is_trusted_dir) { - tor_assert(router->dir_port > 0); - smartlist_add(sl, router); - } + if(!router->is_running || !router->dir_port) + continue; + if(requireauth && !router->is_trusted_dir) + continue; + if(requireothers && router_is_me(router)) + continue; + smartlist_add(sl, router); } router = smartlist_choose(sl); smartlist_free(sl); + return router; +} - if(router) - return router; - log_fn(LOG_INFO,"No dirservers are reachable. Trying them all again."); +/** Go through and mark the auth dirservers as up */ +static void mark_all_authdirservers_up(void) { + int i; + routerinfo_t *router; + + if(!routerlist) + return; - /* No running dir servers found? go through and mark them all as up, - * so we cycle through the list again. */ - sl = smartlist_create(); for(i=0; i < smartlist_len(routerlist->routers); i++) { router = smartlist_get(routerlist->routers, i); if(router->is_trusted_dir) { tor_assert(router->dir_port > 0); router->is_running = 1; router->status_set_at = time(NULL); - smartlist_add(sl, router); } } - router = smartlist_choose(sl); - smartlist_free(sl); - if(!router) - log_fn(LOG_WARN,"No dirservers in directory! Returning NULL."); - return router; } /** Return 0 if \exists an authoritative dirserver that's currently |