aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2004-07-20 06:44:16 +0000
committerRoger Dingledine <arma@torproject.org>2004-07-20 06:44:16 +0000
commitf54224ab356eda91f3488ce454617c984caa0b17 (patch)
tree1b5ea4478e2b218bec7a6e7bb4522e01f9463638 /src
parentb4d4a961b114392b9b09b98951e0a36778aba1e1 (diff)
downloadtor-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.c42
-rw-r--r--src/or/or.h2
-rw-r--r--src/or/routerlist.c90
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