Commit e5f064c9 authored by Nick Mathewson's avatar Nick Mathewson 🎨
Browse files

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.)

parent 136ed330
......@@ -20,6 +20,8 @@ Changes in version - 2006-10-??
- Add a REMOTE_REASON field to CIRC events to tell the controller about
why a remote OR told us to close a circuit.
- There's now a GETINFO ns/... field so that controllers can ask Tor
about the current state of a router.
o Security bugfixes:
- When the user sends a NEWNYM signal, clear the client-side DNS
......@@ -30,7 +30,7 @@ N - Test guard unreachable logic; make sure that we actually attempt to
connect to guards that we think are unreachable from time to time.
Make sure that we don't freak out when the network is down.
N - Stop recommending exits as guards?
N - Clients stop dumping old descriptors if the network-statuses
o Clients stop dumping old descriptors if the network-statuses
claim they're still valid.
P - Figure out why dll's compiled in mingw don't work right in WinXP.
P - Figure out why openssl 0.9.8d "make test" fails at sha256t test.
......@@ -76,7 +76,12 @@ N - Simplify authority operation
being a client.
. Reduce resource load
d - Tolerate clock skew on bridge relays.
N - A way to examine router flags from controller.
o A way to examine router flags from controller.
o Specify: GETINFO ns/id/x, ns/name/x, ns/all.
o Implement
N - A way to alert controller when router flags change.
- Implement
d - A way to adjust router flags from the controller
d - a way to pick entries based wholly on extend_info equivalent;
a way to export extend_info equivalent.
......@@ -349,6 +349,18 @@ $Id$
"desc/id/<OR identity>" or "desc/name/<OR nickname>" -- the latest
server descriptor for a given OR, NUL-terminated.
"ns/id/<OR identity>" or "desc/name/<OR nickname>" -- the latest network
status info for a given OR. Network status info is as given in
dir-spec.txt, and reflects the current beliefs of this Tor about the
router in question. [First implemented in] Like
directory clients, controllers MUST tolerate unrecognized flags and
lines. The published date and descriptor digest are those believed to
be best by this Tor, not necessarily those for a descriptor that Tor
currently has.
"ns/all" -- Network status info for all ORs we have an opinion about,
joined by newlines. [First implemented in]
"desc/all-recent" -- the latest server descriptor for every router that
Tor knows about.
......@@ -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));
} else if (!strcmpstart(question, "ns/")) {
return networkstatus_getinfo_helper(question, answer);
} else if (!strcmpstart(question, "unregistered-servers-")) {
*answer = dirserver_getinfo_unregistered(question +
......@@ -1334,8 +1334,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
static cached_dir_t *
#define N_STATUS_FLAGS 6
#define N_STATUS_FLAGS 9
#define RS_ENTRY_LEN \
( /* first line */ \
......@@ -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 ************************/
......@@ -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"
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. */
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));
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;
static void
routerlist_assert_ok(routerlist_t *rl)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment