summaryrefslogtreecommitdiff
path: root/src/or/networkstatus.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2007-12-18 22:39:15 +0000
committerRoger Dingledine <arma@torproject.org>2007-12-18 22:39:15 +0000
commit74d05f4b2cf31d6bbda1a60b9a4d589cf62c9a51 (patch)
tree7b929b6b2ac43390d700fce64fa11cd46fd3e63e /src/or/networkstatus.c
parentb63a247c6817e099ea3666cc31cd1d24a2cf8fb4 (diff)
downloadtor-74d05f4b2cf31d6bbda1a60b9a4d589cf62c9a51.tar.gz
tor-74d05f4b2cf31d6bbda1a60b9a4d589cf62c9a51.zip
answer getinfo ns/purpose/bridge queries
svn:r12860
Diffstat (limited to 'src/or/networkstatus.c')
-rw-r--r--src/or/networkstatus.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 3300c81b51..884bc0a3a6 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -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;
}