[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r12860: answer getinfo ns/purpose/bridge queries (in tor/trunk: doc/spec src/or)



Author: arma
Date: 2007-12-18 17:39:15 -0500 (Tue, 18 Dec 2007)
New Revision: 12860

Modified:
   tor/trunk/doc/spec/control-spec.txt
   tor/trunk/src/or/control.c
   tor/trunk/src/or/dirserv.c
   tor/trunk/src/or/networkstatus.c
   tor/trunk/src/or/or.h
Log:
answer getinfo ns/purpose/bridge queries


Modified: tor/trunk/doc/spec/control-spec.txt
===================================================================
--- tor/trunk/doc/spec/control-spec.txt	2007-12-18 21:37:58 UTC (rev 12859)
+++ tor/trunk/doc/spec/control-spec.txt	2007-12-18 22:39:15 UTC (rev 12860)
@@ -379,8 +379,9 @@
       hex) is <digest>.  Only available if we're downloading extra-info
       documents.
 
-    "ns/id/<OR identity>" or "ns/name/<OR nickname>" -- the latest network
-      status info for a given OR.  Network status info is as given in
+    "ns/id/<OR identity>" or "ns/name/<OR nickname>" -- the latest router
+      status info (v2 directory style) for a given OR.  Router status
+      info is as given in
       dir-spec.txt, and reflects the current beliefs of this Tor about the
       router in question. Like directory clients, controllers MUST
       tolerate unrecognized flags and lines.  The published date and
@@ -388,10 +389,14 @@
       not necessarily those for a descriptor that Tor currently has.
       [First implemented in 0.1.2.3-alpha.]
 
-    "ns/all" -- Network status info (v2 directory style) for all ORs we
+    "ns/all" -- Router status info (v2 directory style) for all ORs we
       have an opinion about, joined by newlines. [First implemented
       in 0.1.2.3-alpha.]
 
+    "ns/purpose/<purpose>" -- Router status info (v2 directory style)
+      for all ORs of this purpose. Mostly designed for /ns/purpose/bridge
+      queries. [First implemented in 0.2.0.13-alpha.]
+
     "desc/all-recent" -- the latest server descriptor for every router that
       Tor knows about.
 
@@ -401,7 +406,8 @@
       3 for details.  (If VERBOSE_NAMES is enabled, the output will
       not conform to dir-spec-v1.txt; instead, the result will be a
       space-separated list of LongName, each preceded by a "!" if it is
-      believed to be not running.)
+      believed to be not running.) This option is deprecated; use
+      "ns/all" instead.
 
     "address-mappings/all"
     "address-mappings/config"

Modified: tor/trunk/src/or/control.c
===================================================================
--- tor/trunk/src/or/control.c	2007-12-18 21:37:58 UTC (rev 12859)
+++ tor/trunk/src/or/control.c	2007-12-18 22:39:15 UTC (rev 12860)
@@ -1453,7 +1453,8 @@
     routerlist_t *routerlist = router_get_routerlist();
     int verbose = control_conn->use_long_names;
     if (!routerlist || !routerlist->routers ||
-        list_server_status(routerlist->routers, answer, verbose ? 2 : 1) < 0) {
+        list_server_status_v1(routerlist->routers, answer,
+                              verbose ? 2 : 1) < 0) {
       return -1;
     }
   } else if (!strcmpstart(question, "extra-info/digest/")) {

Modified: tor/trunk/src/or/dirserv.c
===================================================================
--- tor/trunk/src/or/dirserv.c	2007-12-18 21:37:58 UTC (rev 12859)
+++ tor/trunk/src/or/dirserv.c	2007-12-18 22:39:15 UTC (rev 12860)
@@ -56,8 +56,6 @@
                         uint32_t addr, uint16_t or_port,
                         const char *platform, const char *contact,
                         const char **msg, int should_log);
-static void dirserv_set_router_is_running(routerinfo_t *router,
-                                          time_t now);
 static void clear_cached_dir(cached_dir_t *d);
 
 static int dirserv_add_extrainfo(extrainfo_t *ei, const char **msg);
@@ -915,7 +913,7 @@
 /** Treat a router as alive if
  *    - It's me, and I'm not hibernating.
  * or - We've found it reachable recently. */
-static void
+void
 dirserv_set_router_is_running(routerinfo_t *router, time_t now)
 {
   int answer;
@@ -942,8 +940,8 @@
  * If for_controller is &gt;1, use the verbose nickname format.
  */
 int
-list_server_status(smartlist_t *routers, char **router_status_out,
-                   int for_controller)
+list_server_status_v1(smartlist_t *routers, char **router_status_out,
+                      int for_controller)
 {
   /* List of entries in a router-status style: An optional !, then an optional
    * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
@@ -952,7 +950,8 @@
   time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
   or_options_t *options = get_options();
   /* We include v2 dir auths here too, because they need to answer
-   * controllers. Eventually we'll deprecate this whole function. */
+   * controllers. Eventually we'll deprecate this whole function;
+   * see also networkstatus_getinfo_by_purpose(). */
   int authdir = authdir_mode_publishes_statuses(options);
   tor_assert(router_status_out);
 
@@ -1996,7 +1995,7 @@
  * We assume that ri-\>is_running has already been set, e.g. by
  *   dirserv_set_router_is_running(ri, now);
  */
-static void
+void
 set_routerstatus_from_routerinfo(routerstatus_t *rs,
                                  routerinfo_t *ri, time_t now,
                                  int naming, int exits_can_be_guards,

Modified: tor/trunk/src/or/networkstatus.c
===================================================================
--- tor/trunk/src/or/networkstatus.c	2007-12-18 21:37:58 UTC (rev 12859)
+++ tor/trunk/src/or/networkstatus.c	2007-12-18 22:39:15 UTC (rev 12860)
@@ -1677,6 +1677,49 @@
   return tor_strdup(buf);
 }
 
+/** Alloc and return a string describing routerstatuses for the most
+ * recent info of each router we know about that is of purpose
+ * <b>purpose_string</b>. Return NULL if unrecognized purpose.
+ *
+ * Right now this function is oriented toward listing bridges (you
+ * shouldn't use this for general-purpose routers, since those
+ * should be listed from the consensus, not from the routers list). */
+char *
+networkstatus_getinfo_by_purpose(const char *purpose_string)
+{
+  time_t now = time(NULL);
+  time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
+  char *answer;
+  routerlist_t *rl = router_get_routerlist();
+  smartlist_t *statuses = smartlist_create();
+  uint8_t purpose = router_purpose_from_string(purpose_string);
+  routerstatus_t rs;
+  int bridge_auth = authdir_mode_bridge(get_options());
+
+  if (purpose == ROUTER_PURPOSE_UNKNOWN) {
+    log_info(LD_DIR, "Unrecognized purpose '%s' when listing router statuses.",
+             purpose_string);
+    return NULL;
+  }
+
+  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
+    if (ri->cache_info.published_on < cutoff)
+      continue;
+    if (ri->purpose != purpose)
+      continue;
+    if (bridge_auth && ri->purpose == ROUTER_PURPOSE_BRIDGE)
+      dirserv_set_router_is_running(ri, now);
+    /* then generate and write out status lines for each of them */
+    set_routerstatus_from_routerinfo(&rs, ri, now, 0, 0, 0, 0);
+    smartlist_add(statuses, networkstatus_getinfo_helper_single(&rs));
+  });
+
+  answer = smartlist_join_strings(statuses, "", 0, NULL);
+  SMARTLIST_FOREACH(statuses, char *, cp, tor_free(cp));
+  smartlist_free(statuses);
+  return answer;
+}
+
 /** If <b>question</b> is a string beginning with "ns/" in a format the
  * control interface expects for a GETINFO question, set *<b>answer</b> to a
  * newly-allocated string containing networkstatus lines for the appropriate
@@ -1712,13 +1755,15 @@
     status = router_get_consensus_status_by_id(d);
   } else if (!strcmpstart(question, "ns/name/")) {
     status = router_get_consensus_status_by_nickname(question+8, 0);
+  } else if (!strcmpstart(question, "ns/purpose/")) {
+    *answer = networkstatus_getinfo_by_purpose(question+11);
+    return *answer ? 0 : -1;
   } else {
     return -1;
   }
 
-  if (status) {
+  if (status)
     *answer = networkstatus_getinfo_helper_single(status);
-  }
   return 0;
 }
 

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-12-18 21:37:58 UTC (rev 12859)
+++ tor/trunk/src/or/or.h	2007-12-18 22:39:15 UTC (rev 12860)
@@ -3051,8 +3051,9 @@
 int getinfo_helper_dirserv_unregistered(control_connection_t *conn,
                                         const char *question, char **answer);
 void dirserv_free_descriptors(void);
-int list_server_status(smartlist_t *routers, char **router_status_out,
-                       int for_controller);
+void dirserv_set_router_is_running(routerinfo_t *router, time_t now);
+int list_server_status_v1(smartlist_t *routers, char **router_status_out,
+                          int for_controller);
 int dirserv_dump_directory_to_string(char **dir_out,
                                      crypto_pk_env_t *private_key);
 
@@ -3158,6 +3159,10 @@
 #define DGV_INCLUDE_PENDING 2
 #define DGV_INCLUDE_PREVIOUS 4
 const cached_dir_t *dirvote_get_vote(const char *fp, int flags);
+void set_routerstatus_from_routerinfo(routerstatus_t *rs,
+                                      routerinfo_t *ri, time_t now,
+                                      int naming, int exits_can_be_guards,
+                                      int listbadexits, int listbaddirs);
 void router_clear_status_flags(routerinfo_t *ri);
 networkstatus_vote_t *
 dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
@@ -3348,6 +3353,7 @@
                                                          smartlist_t *descs);
 
 char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
+char *networkstatus_getinfo_by_purpose(const char *purpose_string);
 int getinfo_helper_networkstatus(control_connection_t *conn,
                                  const char *question, char **answer);
 void networkstatus_free_all(void);