Browse Source

Make GETINFO for "network-status" work on non-authdirs

svn:r3837
Nick Mathewson 20 years ago
parent
commit
6e4bccc4ac
5 changed files with 37 additions and 20 deletions
  1. 1 1
      contrib/tor-control.py
  2. 2 1
      doc/TODO
  3. 5 1
      src/or/control.c
  4. 27 16
      src/or/dirserv.c
  5. 2 1
      src/or/or.h

+ 1 - 1
contrib/tor-control.py

@@ -216,7 +216,7 @@ def do_main_loop(host,port):
   print get_option(s,"DirFetchPeriod\n")
   print `get_info(s,"version")`
   #print `get_info(s,"desc/name/moria1")`
-  #print `get_info(s,"network-status")`
+  print `get_info(s,"network-status")`
   print `get_info(s,"addr-mappings/all")`
   print `get_info(s,"addr-mappings/config")`
   print `get_info(s,"addr-mappings/cache")`

+ 2 - 1
doc/TODO

@@ -1,3 +1,4 @@
+
 Legend:
 SPEC!!  - Not specified
 SPEC    - Spec not finalized
@@ -26,7 +27,7 @@ R  o pick the whole path when you start the circuit.
    - controller should have an event to learn about new addressmappings?
    - how do ulimits work on win32, anyway?
    o have a separate config option which caps bandwidth-to-advertise.
-   - Make list_server_status work right on non-directories, so that 
+   o Make list_server_status work right on non-directories, so that 
      getinfo("network-status") control message can work there.
 
 For 0.1.0.x:

+ 5 - 1
src/or/control.c

@@ -561,8 +561,12 @@ handle_getinfo_helper(const char *question, char **answer)
     if (ri && ri->signed_descriptor)
       *answer = tor_strdup(ri->signed_descriptor);
   } else if (!strcmp(question, "network-status")) {
-    if (list_server_status(NULL, answer) < 0)
+    routerlist_t *routerlist;
+    router_get_routerlist(&routerlist);
+    if (!routerlist || !routerlist->routers ||
+        list_server_status(routerlist->routers, NULL, answer) < 0) {
       return -1;
+    }
   } else if (!strcmpstart(question, "addr-mappings/")) {
     time_t min_e, max_e;
     smartlist_t *mappings;

+ 27 - 16
src/or/dirserv.c

@@ -509,12 +509,14 @@ list_single_server_status(routerinfo_t *desc, int is_live,
   return tor_strdup(buf);
 }
 
-/** Allocate the contents of a running-routers line and a router-status line,
- * and store them in *<b>running_routers_out</b> and *<b>router_status_out</b>
- * respectively.  Return 0 on success, -1 on failure.
+/** Based on the routerinfo_ts in <b>routers</b>, allocate the
+ * contents of a running-routers line and a router-status line, and
+ * store them in *<b>running_routers_out</b> and
+ * *<b>router_status_out</b> respectively.  If either is NULL, skip
+ * it.  Return 0 on success, -1 on failure.
  */
 int
-list_server_status(char **running_routers_out, char **router_status_out)
+list_server_status(smartlist_t *routers, char **running_routers_out, char **router_status_out)
 {
   /* List of entries in running-routers style: An optional !, then either
    * a nickname or a dollar-prefixed hexdigest. */
@@ -522,26 +524,32 @@ list_server_status(char **running_routers_out, char **router_status_out)
   /* List of entries in a router-status style: An optional !, then an optional
    * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
   smartlist_t *rs_entries;
-
+  /* XXXX Really, we should merge descriptor_list into routerlist.  But
+   * this is potentially tricky, since the semantics of the two lists
+   * are not quite the same.  In any case, it's not for the 0.1.0.x
+   * series.
+   */
+  int authdir_mode = get_options()->AuthoritativeDir;
   tor_assert(running_routers_out || router_status_out);
 
   rr_entries = smartlist_create();
   rs_entries = smartlist_create();
 
-  if (!descriptor_list)
-    descriptor_list = smartlist_create();
-
-  SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
+  SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
   {
     int is_live;
     connection_t *conn;
     conn = connection_get_by_identity_digest(
                     ri->identity_digest, CONN_TYPE_OR);
-    /* Treat a router as alive if
-     *    - It's me, and I'm not hibernating.
-     * or - we're connected to it. */
-    is_live = (router_is_me(ri) && !we_are_hibernating()) ||
-      (conn && conn->state == OR_CONN_STATE_OPEN);
+    if (authdir_mode) {
+      /* Treat a router as alive if
+       *    - It's me, and I'm not hibernating.
+       * or - we're connected to it. */
+      is_live = (router_is_me(ri) && !we_are_hibernating()) ||
+        (conn && conn->state == OR_CONN_STATE_OPEN);
+    } else {
+      is_live = ri->is_running;
+    }
     smartlist_add(rr_entries, list_single_server_status(ri, is_live, 1));
     smartlist_add(rs_entries, list_single_server_status(ri, is_live, 0));
   });
@@ -610,7 +618,7 @@ dirserv_dump_directory_to_string(char **dir_out,
   if (!descriptor_list)
     descriptor_list = smartlist_create();
 
-  if (list_server_status(&running_routers, &router_status))
+  if (list_server_status(descriptor_list, &running_routers, &router_status))
     return -1;
 
   /* ASN.1-encode the public key.  This is a temporary measure; once
@@ -869,7 +877,10 @@ static int generate_runningrouters(crypto_pk_env_t *private_key)
   time_t published_on;
   char *identity_pkey; /* Identity key, DER64-encoded. */
 
-  if (list_server_status(NULL, &router_status)) {
+  if (!descriptor_list)
+    descriptor_list = smartlist_create();
+
+  if (list_server_status(descriptor_list, NULL, &router_status)) {
     goto err;
   }
   /* ASN.1-encode the public key.  This is a temporary measure; once

+ 2 - 1
src/or/or.h

@@ -1460,7 +1460,8 @@ const char *dirserv_get_nickname_by_digest(const char *digest);
 int dirserv_add_descriptor(const char **desc, const char **msg);
 int dirserv_load_from_directory_string(const char *dir);
 void dirserv_free_descriptors(void);
-int list_server_status(char **running_routers_out, char **router_status_out);
+int list_server_status(smartlist_t *routers,
+                       char **running_routers_out, char **router_status_out);
 void dirserv_remove_old_servers(int age);
 int dirserv_dump_directory_to_string(char **dir_out,
                                      crypto_pk_env_t *private_key);