Commit 74d05f4b authored by Roger Dingledine's avatar Roger Dingledine
Browse files

answer getinfo ns/purpose/bridge queries


svn:r12860
parent b63a247c
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -379,8 +379,9 @@ $Id$
      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 @@ $Id$
      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 @@ $Id$
      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"
+2 −1
Original line number Diff line number Diff line
@@ -1453,7 +1453,8 @@ getinfo_helper_dir(control_connection_t *control_conn,
    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/")) {
+6 −7
Original line number Diff line number Diff line
@@ -56,8 +56,6 @@ dirserv_get_status_impl(const char *fp, const char *nickname,
                        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 @@ list_single_server_status(routerinfo_t *desc, int is_live)
/** 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,7 +940,7 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
 * If for_controller is &gt;1, use the verbose nickname format.
 */
int
list_server_status(smartlist_t *routers, char **router_status_out,
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
@@ -952,7 +950,8 @@ list_server_status(smartlist_t *routers, char **router_status_out,
  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 @@ get_possible_sybil_list(const smartlist_t *routers)
 * 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,
+47 −2
Original line number Diff line number Diff line
@@ -1677,6 +1677,49 @@ networkstatus_getinfo_helper_single(routerstatus_t *rs)
  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 @@ getinfo_helper_networkstatus(control_connection_t *conn,
    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;
}

+8 −2
Original line number Diff line number Diff line
@@ -3051,7 +3051,8 @@ int dirserv_add_descriptor(routerinfo_t *ri, const char **msg);
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,
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 @@ const char *dirvote_get_pending_detached_signatures(void);
#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 @@ void signed_descs_update_status_from_consensus_networkstatus(
                                                         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);