mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 14:51:11 +01:00
Implement GETINFO md/all
This commit is contained in:
parent
3716ddf1b4
commit
25341245ae
3 changed files with 102 additions and 0 deletions
3
changes/feature8323
Normal file
3
changes/feature8323
Normal file
|
@ -0,0 +1,3 @@
|
|||
o Minor features (controller):
|
||||
- Implement 'GETINFO md/all' controller command to enable
|
||||
getting all known microdesriptors. Closes ticket 8323.
|
|
@ -2207,6 +2207,27 @@ getinfo_helper_dir(control_connection_t *control_conn,
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(question, "md/all")) {
|
||||
const smartlist_t *nodes = nodelist_get_list();
|
||||
tor_assert(nodes);
|
||||
|
||||
if (smartlist_len(nodes) == 0) {
|
||||
*answer = tor_strdup("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
smartlist_t *microdescs = smartlist_new();
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(nodes, node_t *, n) {
|
||||
if (n->md && n->md->body) {
|
||||
char *copy = tor_strndup(n->md->body, n->md->bodylen);
|
||||
smartlist_add(microdescs, copy);
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(n);
|
||||
|
||||
*answer = smartlist_join_strings(microdescs, "", 0, NULL);
|
||||
SMARTLIST_FOREACH(microdescs, char *, md, tor_free(md));
|
||||
smartlist_free(microdescs);
|
||||
} else if (!strcmpstart(question, "md/id/")) {
|
||||
const node_t *node = node_get_by_hex_id(question+strlen("md/id/"), 0);
|
||||
const microdesc_t *md = NULL;
|
||||
|
@ -3241,6 +3262,7 @@ static const getinfo_item_t getinfo_items[] = {
|
|||
ITEM("desc/download-enabled", dir,
|
||||
"Do we try to download router descriptors?"),
|
||||
ITEM("desc/all-recent-extrainfo-hack", dir, NULL), /* Hack. */
|
||||
ITEM("md/all", dir, "All known microdescriptors."),
|
||||
PREFIX("md/id/", dir, "Microdescriptors by ID"),
|
||||
PREFIX("md/name/", dir, "Microdescriptors by name"),
|
||||
ITEM("md/download-enabled", dir,
|
||||
|
@ -3400,6 +3422,7 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len,
|
|||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
SMARTLIST_FOREACH_BEGIN(questions, const char *, q) {
|
||||
const char *errmsg = NULL;
|
||||
|
||||
if (handle_getinfo_helper(conn, q, &ans, &errmsg) < 0) {
|
||||
if (!errmsg)
|
||||
errmsg = "Internal error";
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "networkstatus.h"
|
||||
#include "rendservice.h"
|
||||
#include "routerlist.h"
|
||||
#include "nodelist.h"
|
||||
#include "test.h"
|
||||
#include "test_helpers.h"
|
||||
|
||||
|
@ -1525,6 +1526,80 @@ test_current_time(void *arg)
|
|||
return;
|
||||
}
|
||||
|
||||
static size_t n_nodelist_get_list = 0;
|
||||
static smartlist_t *nodes = NULL;
|
||||
|
||||
static smartlist_t *
|
||||
mock_nodelist_get_list(void)
|
||||
{
|
||||
n_nodelist_get_list++;
|
||||
tor_assert(nodes);
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
static void
|
||||
test_getinfo_md_all(void *arg)
|
||||
{
|
||||
char *answer = NULL;
|
||||
const char *errmsg = NULL;
|
||||
int retval = 0;
|
||||
|
||||
(void)arg;
|
||||
|
||||
node_t *node1 = tor_malloc(sizeof(node_t));
|
||||
memset(node1, 0, sizeof(node_t));
|
||||
node1->md = tor_malloc(sizeof(microdesc_t));
|
||||
memset(node1->md, 0, sizeof(microdesc_t));
|
||||
node1->md->body = tor_strdup("md1\n");
|
||||
node1->md->bodylen = 4;
|
||||
|
||||
node_t *node2 = tor_malloc(sizeof(node_t));
|
||||
memset(node2, 0, sizeof(node_t));
|
||||
node2->md = tor_malloc(sizeof(microdesc_t));
|
||||
memset(node2->md, 0, sizeof(microdesc_t));
|
||||
node2->md->body = tor_strdup("md2\n");
|
||||
node2->md->bodylen = 4;
|
||||
|
||||
MOCK(nodelist_get_list, mock_nodelist_get_list);
|
||||
|
||||
nodes = smartlist_new();
|
||||
|
||||
retval = getinfo_helper_dir(NULL, "md/all", &answer, &errmsg);
|
||||
|
||||
tt_int_op(n_nodelist_get_list, OP_EQ, 1);
|
||||
tt_int_op(retval, OP_EQ, 0);
|
||||
tt_assert(answer != NULL);
|
||||
tt_assert(errmsg == NULL);
|
||||
tt_str_op(answer, OP_EQ, "");
|
||||
|
||||
tor_free(answer);
|
||||
|
||||
smartlist_add(nodes, node1);
|
||||
smartlist_add(nodes, node2);
|
||||
|
||||
retval = getinfo_helper_dir(NULL, "md/all", &answer, &errmsg);
|
||||
|
||||
tt_int_op(n_nodelist_get_list, OP_EQ, 2);
|
||||
tt_int_op(retval, OP_EQ, 0);
|
||||
tt_assert(answer != NULL);
|
||||
tt_assert(errmsg == NULL);
|
||||
|
||||
tt_str_op(answer, OP_EQ, "md1\nmd2\n");
|
||||
|
||||
done:
|
||||
UNMOCK(nodelist_get_list);
|
||||
tor_free(node1->md->body);
|
||||
tor_free(node1->md);
|
||||
tor_free(node1);
|
||||
tor_free(node2->md->body);
|
||||
tor_free(node2->md);
|
||||
tor_free(node2);
|
||||
tor_free(answer);
|
||||
smartlist_free(nodes);
|
||||
return;
|
||||
}
|
||||
|
||||
struct testcase_t controller_tests[] = {
|
||||
{ "add_onion_helper_keyarg_v2", test_add_onion_helper_keyarg_v2, 0,
|
||||
NULL, NULL },
|
||||
|
@ -1542,6 +1617,7 @@ struct testcase_t controller_tests[] = {
|
|||
{ "download_status_desc", test_download_status_desc, 0, NULL, NULL },
|
||||
{ "download_status_bridge", test_download_status_bridge, 0, NULL, NULL },
|
||||
{ "current_time", test_current_time, 0, NULL, NULL },
|
||||
{ "getinfo_md_all", test_getinfo_md_all, 0, NULL, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue