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
This commit is contained in:
Nick Mathewson 2006-10-20 14:58:29 +00:00
parent 136ed33071
commit e5f064c983
7 changed files with 126 additions and 4 deletions

View File

@ -20,6 +20,8 @@ Changes in version 0.1.2.3-alpha - 2006-10-??
Perry)
- 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

View File

@ -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.
- Specify: SETEVENTS NS
- 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.

View File

@ -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 0.1.2.3-alpha] 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 0.1.2.3-alpha.]
"desc/all-recent" -- the latest server descriptor for every router that
Tor knows about.

View File

@ -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-"));

View File

@ -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+ \

View File

@ -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

View File

@ -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)
{