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 | |
parent | b63a247c6817e099ea3666cc31cd1d24a2cf8fb4 (diff) | |
download | tor-74d05f4b2cf31d6bbda1a60b9a4d589cf62c9a51.tar.gz tor-74d05f4b2cf31d6bbda1a60b9a4d589cf62c9a51.zip |
answer getinfo ns/purpose/bridge queries
svn:r12860
-rw-r--r-- | doc/spec/control-spec.txt | 14 | ||||
-rw-r--r-- | src/or/control.c | 3 | ||||
-rw-r--r-- | src/or/dirserv.c | 13 | ||||
-rw-r--r-- | src/or/networkstatus.c | 49 | ||||
-rw-r--r-- | src/or/or.h | 10 |
5 files changed, 73 insertions, 16 deletions
diff --git a/doc/spec/control-spec.txt b/doc/spec/control-spec.txt index dcb4ffa4c3..2e31be13d1 100644 --- a/doc/spec/control-spec.txt +++ b/doc/spec/control-spec.txt @@ -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" diff --git a/src/or/control.c b/src/or/control.c index e404a4beb7..af1bb42f60 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -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/")) { diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 5f19d15515..e45a6ea8f7 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -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,8 +940,8 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now) * If for_controller is >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 @@ 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, 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; } diff --git a/src/or/or.h b/src/or/or.h index b324b2e162..a59e7459b2 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3051,8 +3051,9 @@ 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, - 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 @@ 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); |