diff options
author | Roger Dingledine <arma@torproject.org> | 2007-12-18 22:39:15 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2007-12-18 22:39:15 +0000 |
commit | 74d05f4b2cf31d6bbda1a60b9a4d589cf62c9a51 (patch) | |
tree | 7b929b6b2ac43390d700fce64fa11cd46fd3e63e /src/or/networkstatus.c | |
parent | b63a247c6817e099ea3666cc31cd1d24a2cf8fb4 (diff) | |
download | tor-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.c | 49 |
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; } |