diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-10-20 14:58:29 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-10-20 14:58:29 +0000 |
commit | e5f064c983eba136e3d448914995e79f1f55959d (patch) | |
tree | 2efab188a013149c6f8977539c3c63daa4c1e761 /src | |
parent | 136ed3307140ff82ade78f21765e43c87902d240 (diff) | |
download | tor-e5f064c983eba136e3d448914995e79f1f55959d.tar.gz tor-e5f064c983eba136e3d448914995e79f1f55959d.zip |
r9290@31-35-219: nickm | 2006-10-20 10:32:33 -0400
Add a GETINFO target so controllers can ask Tor for the current state of a router. (Results given in networkstatus format.)
svn:r8772
Diffstat (limited to 'src')
-rw-r--r-- | src/or/control.c | 3 | ||||
-rw-r--r-- | src/or/dirserv.c | 4 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/routerlist.c | 98 |
4 files changed, 105 insertions, 2 deletions
diff --git a/src/or/control.c b/src/or/control.c index 167b0e7ba5..84d4ee4d56 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1437,6 +1437,7 @@ list_getinfo_options(void) "orconn-status Status of each current OR connection.\n" "stream-status Status of each current application stream.\n" "version The current version of Tor.\n"); + // XXXX Uptodate! } /** Lookup the 'getinfo' entry <b>question</b>, and return @@ -1493,6 +1494,8 @@ handle_getinfo_helper(control_connection_t *control_conn, *answer = smartlist_join_strings(sl, "", 0, NULL); SMARTLIST_FOREACH(sl, char *, c, tor_free(c)); smartlist_free(sl); + } else if (!strcmpstart(question, "ns/")) { + return networkstatus_getinfo_helper(question, answer); } else if (!strcmpstart(question, "unregistered-servers-")) { *answer = dirserver_getinfo_unregistered(question + strlen("unregistered-servers-")); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 355dcef52b..d4acc0cd4a 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1334,8 +1334,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl) static cached_dir_t * generate_v2_networkstatus(void) { -#define LONGEST_STATUS_FLAG_NAME_LEN 7 -#define N_STATUS_FLAGS 6 +#define LONGEST_STATUS_FLAG_NAME_LEN 9 +#define N_STATUS_FLAGS 9 #define RS_ENTRY_LEN \ ( /* first line */ \ MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \ diff --git a/src/or/or.h b/src/or/or.h index f44f8a2a90..86c626a779 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2668,6 +2668,8 @@ void router_reset_status_download_failures(void); int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2); const char *esc_router_info(routerinfo_t *router); +int networkstatus_getinfo_helper(const char *question, char **answer); + /********************************* routerparse.c ************************/ #define MAX_STATUS_TAG_LEN 32 diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 25e54dfef7..3ec7d7ffeb 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -4109,6 +4109,104 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2) return 1; } +/** Generate networkstatus lines for a single routerstatus_t object, and + * return the result in a newly allocated string. Used only by controller + * interface (for now.) */ +/* XXXX This should eventually merge into generate_v2_networkstatus() */ +static char * +networkstatus_getinfo_helper_single(routerstatus_t *rs) +{ + char buf[192]; + int r; + struct in_addr in; + + int f_authority; + char published[ISO_TIME_LEN+1]; + char ipaddr[INET_NTOA_BUF_LEN]; + char identity64[BASE64_DIGEST_LEN+1]; + char digest64[BASE64_DIGEST_LEN+1]; + + format_iso_time(published, rs->published_on); + digest_to_base64(identity64, rs->identity_digest); + digest_to_base64(digest64, rs->descriptor_digest); + in.s_addr = htonl(rs->addr); + tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr)); + + f_authority = router_digest_is_trusted_dir(rs->identity_digest); + + r = tor_snprintf(buf, sizeof(buf), + "r %s %s %s %s %s %d %d\n" + "s%s%s%s%s%s%s%s%s%s%s\n", + rs->nickname, + identity64, + digest64, + published, + ipaddr, + (int)rs->or_port, + (int)rs->dir_port, + + f_authority?" Authority":"", + rs->is_bad_exit?" BadExit":"", + rs->is_exit?" Exit":"", + rs->is_fast?" Fast":"", + rs->is_possible_guard?" Guard":"", + rs->is_named?" Named":"", + rs->is_stable?" Stable":"", + rs->is_running?" Running":"", + rs->is_valid?" Valid":"", + rs->is_v2_dir?" V2Dir":""); + if (r<0) + log_warn(LD_BUG, "Not enough space in buffer."); + + return tor_strdup(buf); +} + +/** 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 + * ORs. Return 0 on success, -1 on failure. */ +int +networkstatus_getinfo_helper(const char *question, char **answer) +{ + local_routerstatus_t *status; + + if (!routerstatus_list) { + *answer = tor_strdup(""); + return 0; + } + + if (!strcmpstart(question, "ns/all")) { + smartlist_t *statuses = smartlist_create(); + SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, lrs, + { + routerstatus_t *rs = &(lrs->status); + 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 0; + } else if (!strcmpstart(question, "ns/id/")) { + char d[DIGEST_LEN]; + + if (base16_decode(d, DIGEST_LEN, question+6, strlen(question+6))) + return -1; + status = router_get_combined_status_by_digest(d); + } else if (!strcmpstart(question, "ns/name/")) { + status = router_get_combined_status_by_nickname(question+8, 0); + } else { + return -1; + } + + if (status) { + *answer = networkstatus_getinfo_helper_single(&status->status); + } else { + *answer = tor_strdup(""); + } + return 0; +} + +/*DOCDOC*/ static void routerlist_assert_ok(routerlist_t *rl) { |