Unverified Commit 6413b210 authored by AmreshVenugopal's avatar AmreshVenugopal Committed by teor
Browse files

control: Add GETINFO support for dumping microdesc consensus

- Allows control port to read microdesc consensus using:
GETINFO dir/status-vote/microdesc/consensus

add: Helper function `getinfo_helper_current_consensus`
test: check if GETINFO commands return expected consensus data.

Resolves 31684.
parent 6846d148
Loading
Loading
Loading
Loading

changes/ticket31684

0 → 100644
+6 −0
Original line number Diff line number Diff line
  o Minor features (onion services):
    - Implement a new GETINFO command to fetch microdescriptor consensus.
      Closes ticket 31684.
  o Code simplification and refactoring (onion services):
    - Create a helper function that can fetch network status or microdesc
      consensuses.
+49 −16
Original line number Diff line number Diff line
@@ -325,6 +325,42 @@ getinfo_helper_current_time(control_connection_t *control_conn,
  return 0;
}

/** GETINFO helper for dumping different consensus flavors
 * returns: 0 on success -1 on error. */
STATIC int
getinfo_helper_current_consensus(consensus_flavor_t flavor,
                                 char** answer,
                                 const char** errmsg)
{
  const char *flavor_name = networkstatus_get_flavor_name(flavor);
  if (!strcmp(flavor_name, "??")) {
    *errmsg = "Could not open cached consensus. "
      "Make sure FetchUselessDescriptors is set to 1.";
    return -1;
  }
  if (we_want_to_fetch_flavor(get_options(), flavor)) {
    /** Check from the cache */
    const cached_dir_t *consensus = dirserv_get_consensus(flavor_name);
    if (consensus) {
      *answer = tor_strdup(consensus->dir);
    }
  }
  if (!*answer) { /* try loading it from disk */

    tor_mmap_t *mapped = networkstatus_map_cached_consensus(flavor_name);
    if (mapped) {
      *answer = tor_memdup_nulterm(mapped->data, mapped->size);
      tor_munmap_file(mapped);
    }
    if (!*answer) { /* generate an error */
      *errmsg = "Could not open cached consensus. "
        "Make sure FetchUselessDescriptors is set to 1.";
      return -1;
    }
  }
  return 0;
}

/** Implementation helper for GETINFO: knows the answers for questions about
 * directory information. */
STATIC int
@@ -576,23 +612,18 @@ getinfo_helper_dir(control_connection_t *control_conn,
    smartlist_free(descs);
  } else if (!strcmpstart(question, "dir/status/")) {
    *answer = tor_strdup("");
  } else if (!strcmp(question, "dir/status-vote/current/consensus")) { /* v3 */
    if (we_want_to_fetch_flavor(get_options(), FLAV_NS)) {
      const cached_dir_t *consensus = dirserv_get_consensus("ns");
      if (consensus)
        *answer = tor_strdup(consensus->dir);
    }
    if (!*answer) { /* try loading it from disk */
      tor_mmap_t *mapped = networkstatus_map_cached_consensus("ns");
      if (mapped) {
        *answer = tor_memdup_nulterm(mapped->data, mapped->size);
        tor_munmap_file(mapped);
      }
      if (!*answer) { /* generate an error */
        *errmsg = "Could not open cached consensus. "
          "Make sure FetchUselessDescriptors is set to 1.";
  } else if (!strcmp(question, "dir/status-vote/current/consensus")) {
    int consensus_result = getinfo_helper_current_consensus(FLAV_NS,
                                                            answer, errmsg);
    if (consensus_result == -1) {
      return -1;
    }
  } else if (!strcmp(question,
                     "dir/status-vote/current/consensus-microdesc")) {
    int consensus_result = getinfo_helper_current_consensus(FLAV_MICRODESC,
                                                            answer, errmsg);
    if (consensus_result == -1) {
      return -1;
    }
  } else if (!strcmp(question, "network-status")) { /* v1 */
    static int network_status_warned = 0;
@@ -1513,6 +1544,8 @@ static const getinfo_item_t getinfo_items[] = {
         "v2 networkstatus docs as retrieved from a DirPort."),
  ITEM("dir/status-vote/current/consensus", dir,
       "v3 Networkstatus consensus as retrieved from a DirPort."),
  ITEM("dir/status-vote/current/consensus-microdesc", dir,
       "v3 Microdescriptors consensus as retrieved from a DirPort."),
  ITEM("exit-policy/default", policies,
       "The default value appended to the configured exit policy."),
  ITEM("exit-policy/reject-private/default", policies,
+4 −0
Original line number Diff line number Diff line
@@ -48,6 +48,10 @@ STATIC int getinfo_helper_downloads(
    control_connection_t *control_conn,
    const char *question, char **answer,
    const char **errmsg);
STATIC int getinfo_helper_current_consensus(
    consensus_flavor_t flavor,
    char **answer,
    const char **errmsg);
STATIC int getinfo_helper_dir(
    control_connection_t *control_conn,
    const char *question, char **answer,
+2 −2
Original line number Diff line number Diff line
@@ -259,8 +259,8 @@ dirserv_set_cached_consensus_networkstatus(const char *networkstatus,

/** Return the latest downloaded consensus networkstatus in encoded, signed,
 * optionally compressed format, suitable for sending to clients. */
cached_dir_t *
dirserv_get_consensus(const char *flavor_name)
MOCK_IMPL(cached_dir_t *,
dirserv_get_consensus,(const char *flavor_name))
{
  if (!cached_consensuses)
    return NULL;
+1 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ int directory_permits_begindir_requests(const or_options_t *options);
int directory_too_idle_to_fetch_descriptors(const or_options_t *options,
                                            time_t now);

cached_dir_t *dirserv_get_consensus(const char *flavor_name);
MOCK_DECL(cached_dir_t *, dirserv_get_consensus, (const char *flavor_name));
void dirserv_set_cached_consensus_networkstatus(const char *consensus,
                                              size_t consensus_len,
                                              const char *flavor_name,
Loading