mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Add router descriptor download status queries to GETINFO
This commit is contained in:
@@ -2307,6 +2307,52 @@ getinfo_helper_downloads_cert(const char *fp_sk_req,
|
||||
}
|
||||
}
|
||||
|
||||
/** Handle the routerdesc download cases for getinfo_helper_downloads() */
|
||||
static void
|
||||
getinfo_helper_downloads_desc(const char *desc_req,
|
||||
download_status_t **dl_to_emit,
|
||||
smartlist_t **digest_list,
|
||||
const char **errmsg)
|
||||
{
|
||||
char desc_digest[DIGEST_LEN];
|
||||
/*
|
||||
* Two cases to handle here:
|
||||
*
|
||||
* Case 1: desc_req = "descs"
|
||||
* - Emit a list of all router descriptor digests, which we get by
|
||||
* calling router_get_descriptor_digests(); this can return NULL
|
||||
* if we have no current ns-flavor consensus.
|
||||
*
|
||||
* Case 2: desc_req = <fp>
|
||||
* - Check on the specified fingerprint and emit its download_status_t
|
||||
* using router_get_dl_status_by_descriptor_digest().
|
||||
*/
|
||||
|
||||
if (strcmp(desc_req, "descs") == 0) {
|
||||
*digest_list = router_get_descriptor_digests();
|
||||
if (!(*digest_list)) {
|
||||
*errmsg = "We don't seem to have a networkstatus-flavored consensus";
|
||||
}
|
||||
/*
|
||||
* Microdescs don't use the download_status_t mechanism, so we don't
|
||||
* answer queries about their downloads here; see microdesc.c.
|
||||
*/
|
||||
} else if (strlen(desc_req) == HEX_DIGEST_LEN) {
|
||||
if (base16_decode(desc_digest, DIGEST_LEN,
|
||||
desc_req, strlen(desc_req)) == DIGEST_LEN) {
|
||||
/* Okay we got a digest-shaped thing; try asking for it */
|
||||
*dl_to_emit = router_get_dl_status_by_descriptor_digest(desc_digest);
|
||||
if (!(*dl_to_emit)) {
|
||||
*errmsg = "No such descriptor digest found";
|
||||
}
|
||||
} else {
|
||||
*errmsg = "That didn't look like a digest";
|
||||
}
|
||||
} else {
|
||||
*errmsg = "Unknown router descriptor download status query";
|
||||
}
|
||||
}
|
||||
|
||||
/** Implementation helper for GETINFO: knows the answers for questions about
|
||||
* download status information. */
|
||||
static int
|
||||
@@ -2335,6 +2381,10 @@ getinfo_helper_downloads(control_connection_t *control_conn,
|
||||
getinfo_helper_downloads_cert(
|
||||
question + strlen("downloads/cert/"),
|
||||
&dl_to_emit, &digest_list, errmsg);
|
||||
} else if (!strcmpstart(question, "downloads/desc/")) {
|
||||
getinfo_helper_downloads_desc(
|
||||
question + strlen("downloads/desc/"),
|
||||
&dl_to_emit, &digest_list, errmsg);
|
||||
} else {
|
||||
*errmsg = "Unknown download status query";
|
||||
}
|
||||
@@ -2826,6 +2876,12 @@ static const getinfo_item_t getinfo_items[] = {
|
||||
DOC("downloads/cert/fp/<fp>/<sk>",
|
||||
"Download status for <fp> with signing key <sk>; corresponds "
|
||||
"to /fp-sk/ URLs on directory server."),
|
||||
PREFIX("downloads/desc/", downloads,
|
||||
"Download statuses for router descriptors, by descriptor digest"),
|
||||
DOC("downloads/desc/descs",
|
||||
"Return a list of known router descriptor digests"),
|
||||
DOC("downloads/desc/<desc>",
|
||||
"Return a download status for a given descriptor digest"),
|
||||
ITEM("info/names", misc,
|
||||
"List of GETINFO options, types, and documentation."),
|
||||
ITEM("events/names", misc,
|
||||
|
||||
@@ -659,6 +659,43 @@ router_get_consensus_status_by_descriptor_digest(networkstatus_t *consensus,
|
||||
consensus, digest);
|
||||
}
|
||||
|
||||
/** Return a smartlist of all router descriptor digests in a consensus */
|
||||
static smartlist_t *
|
||||
router_get_descriptor_digests_in_consensus(networkstatus_t *consensus)
|
||||
{
|
||||
smartlist_t *result = smartlist_new();
|
||||
digestmap_iter_t *i;
|
||||
const char *digest;
|
||||
void *rs;
|
||||
char *digest_tmp;
|
||||
|
||||
for (i = digestmap_iter_init(consensus->desc_digest_map);
|
||||
!(digestmap_iter_done(i));
|
||||
i = digestmap_iter_next(consensus->desc_digest_map, i)) {
|
||||
digestmap_iter_get(i, &digest, &rs);
|
||||
digest_tmp = tor_malloc(DIGEST_LEN);
|
||||
memcpy(digest_tmp, digest, DIGEST_LEN);
|
||||
smartlist_add(result, digest_tmp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Return a smartlist of all router descriptor digests in the current
|
||||
* consensus */
|
||||
smartlist_t *
|
||||
router_get_descriptor_digests(void)
|
||||
{
|
||||
smartlist_t *result = NULL;
|
||||
|
||||
if (current_ns_consensus) {
|
||||
result =
|
||||
router_get_descriptor_digests_in_consensus(current_ns_consensus);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Given the digest of a router descriptor, return its current download
|
||||
* status, or NULL if the digest is unrecognized. */
|
||||
MOCK_IMPL(download_status_t *,
|
||||
|
||||
@@ -45,6 +45,7 @@ download_status_t * networkstatus_get_dl_status_by_flavor_bootstrap(
|
||||
download_status_t * networkstatus_get_dl_status_by_flavor_running(
|
||||
consensus_flavor_t flavor);
|
||||
|
||||
smartlist_t * router_get_descriptor_digests(void);
|
||||
MOCK_DECL(download_status_t *,router_get_dl_status_by_descriptor_digest,
|
||||
(const char *d));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user