diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/or/control.c | 51 | ||||
-rw-r--r-- | src/or/dirserv.c | 23 |
3 files changed, 54 insertions, 23 deletions
@@ -26,6 +26,9 @@ Changes in version 0.1.2.5-xxxx - 200?-??-?? - When generating bandwidth history, round down to the nearest 1k. When storing accounting data, round up to the nearest 1k. + o Controller features + - Have GETINFO dir/status/* work on hosts with DirPort disabled. + o Controller bugfixes: - Report the circuit number correctly in STREAM CLOSED events. (Bug reported by Mike Perry.) diff --git a/src/or/control.c b/src/or/control.c index 9470e49e0d..e07b81b1f6 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1449,6 +1449,7 @@ list_getinfo_options(void) "desc/name/* Server descriptor by nickname.\n" "desc/all-recent Latest server descriptor for every router.\n" "dir/server/* Fetch server descriptors -- see dir-spec.txt.\n" + "dir/status/* Fetch networkstatus documents -- see dir-spec.txt.\n" "entry-guards Which nodes will we use as entry guards?\n" "events/names What events the controller can ask for.\n" "exit-policy/default Default lines appended to config->ExitPolicy.\n" @@ -1708,24 +1709,44 @@ handle_getinfo_helper(control_connection_t *control_conn, tor_free(url); smartlist_free(descs); } else if (!strcmpstart(question, "dir/status/")) { - smartlist_t *status_list; size_t len; char *cp; - if (!get_options()->DirPort) { - log_warn(LD_CONTROL, "getinfo dir/status/ requires an open dirport."); - return -1; + if (get_options()->DirPort) { + smartlist_t *status_list = smartlist_create(); + dirserv_get_networkstatus_v2(status_list, + question+strlen("dir/status/")); + SMARTLIST_FOREACH(status_list, cached_dir_t *, d, len += d->dir_len); + len = 0; + cp = *answer = tor_malloc(len+1); + SMARTLIST_FOREACH(status_list, cached_dir_t *, d, { + memcpy(cp, d->dir, d->dir_len); + cp += d->dir_len; + }); + *cp = '\0'; + smartlist_free(status_list); + } else { + smartlist_t *fp_list = smartlist_create(); + smartlist_t *status_list = smartlist_create(); + size_t fn_len = strlen(get_options()->DataDirectory)+HEX_DIGEST_LEN+32; + char *fn = tor_malloc(fn_len+1); + char hex_id[HEX_DIGEST_LEN+1]; + dirserv_get_networkstatus_v2_fingerprints( + fp_list, question+strlen("dir/status/")); + SMARTLIST_FOREACH(fp_list, const char *, fp, { + char *s; + base16_encode(hex_id, sizeof(hex_id), fp, DIGEST_LEN); + tor_snprintf(fn, fn_len, "%s/cached-status/%s", + get_options()->DataDirectory, hex_id); + s = read_file_to_str(fn, 0, NULL); + if (s) + smartlist_add(status_list, s); + }); + SMARTLIST_FOREACH(fp_list, char *, fp, tor_free(fp)); + smartlist_free(fp_list); + *answer = smartlist_join_strings(status_list, "", 0, NULL); + SMARTLIST_FOREACH(status_list, char *, s, tor_free(s)); + smartlist_free(status_list); } - status_list = smartlist_create(); - dirserv_get_networkstatus_v2(status_list, - question+strlen("dir/status/")); - len = 0; - SMARTLIST_FOREACH(status_list, cached_dir_t *, d, len += d->dir_len); - cp = *answer = tor_malloc(len+1); - SMARTLIST_FOREACH(status_list, cached_dir_t *, d, { - memcpy(cp, d->dir, d->dir_len); - cp += d->dir_len; - }); - *cp = '\0'; } else if (!strcmpstart(question, "exit-policy/")) { return policies_getinfo_helper(question, answer); } diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 473b7f6ad7..cccc494f4d 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1578,6 +1578,7 @@ generate_v2_networkstatus(void) } /* DOCDOC */ +/* XXXX This can be replace a lot of dirserv_get_networkstatus_v2(). */ void dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result, const char *key) @@ -1598,14 +1599,20 @@ dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result, tor_memdup(me->cache_info.identity_digest, DIGEST_LEN)); } } else if (!strcmp(key, "all")) { - digestmap_iter_t *iter; - iter = digestmap_iter_init(cached_v2_networkstatus); - while (!digestmap_iter_done(iter)) { - const char *ident; - void *val; - digestmap_iter_get(iter, &ident, &val); - smartlist_add(result, tor_memdup(ident, DIGEST_LEN)); - iter = digestmap_iter_next(cached_v2_networkstatus, iter); + if (digestmap_size(cached_v2_networkstatus)) { + digestmap_iter_t *iter; + iter = digestmap_iter_init(cached_v2_networkstatus); + while (!digestmap_iter_done(iter)) { + const char *ident; + void *val; + digestmap_iter_get(iter, &ident, &val); + smartlist_add(result, tor_memdup(ident, DIGEST_LEN)); + iter = digestmap_iter_next(cached_v2_networkstatus, iter); + } + } else { + SMARTLIST_FOREACH(router_get_trusted_dir_servers(), + trusted_dir_server_t *, ds, + smartlist_add(result, tor_memdup(ds->digest, DIGEST_LEN))); } smartlist_sort_digests(result); if (smartlist_len(result) == 0) |