[or-cvs] clients can now pick non-authdirservers for fetching direct...

Roger Dingledine arma at seul.org
Tue Jul 20 06:44:19 UTC 2004


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	or.h directory.c routerlist.c 
Log Message:
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.


Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.382
retrieving revision 1.383
diff -u -d -r1.382 -r1.383
--- or.h	18 Jul 2004 21:47:04 -0000	1.382
+++ or.h	20 Jul 2004 06:44:16 -0000	1.383
@@ -1355,7 +1355,7 @@
 
 /********************************* 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);

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -d -r1.116 -r1.117
--- directory.c	20 Jul 2004 02:44:26 -0000	1.116
+++ directory.c	20 Jul 2004 06:44:16 -0000	1.117
@@ -80,11 +80,27 @@
 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 @@
 {
   connection_t *conn;
 
+  tor_assert(router);
+  tor_assert(router->dir_port);
+
   switch (purpose)
     {
     case DIR_PURPOSE_FETCH_DIR:
@@ -121,13 +140,6 @@
       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 @@
     }
   } 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 @@
  * 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 @@
       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' */

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerlist.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -d -r1.99 -r1.100
--- routerlist.c	18 Jul 2004 21:47:04 -0000	1.99
+++ routerlist.c	20 Jul 2004 06:44:16 -0000	1.100
@@ -19,7 +19,9 @@
 /* ********************************************************************** */
 
 /* 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 @@
 
 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 @@
   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



More information about the tor-commits mailing list