Commit 200c39b6 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Document the microdescriptor code better.

parent d61b5df9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1481,7 +1481,8 @@ crypto_digest_algorithm_get_name(digest_algorithm_t alg)
  }
}

/** DOCDOC */
/** Given the name of a digest algorithm, return its integer value, or -1 if
 * the name is not recognized. */
int
crypto_digest_algorithm_parse_name(const char *name)
{
+2 −1
Original line number Diff line number Diff line
@@ -1885,7 +1885,8 @@ version_from_platform(const char *platform)
 * The format argument has three possible values:
 *   NS_V2 - Output an entry suitable for a V2 NS opinion document
 *   NS_V3_CONSENSUS - Output the first portion of a V3 NS consensus entry
 *   NS_V3_CONSENSUS_MICRODESC - DOCDOC
 *   NS_V3_CONSENSUS_MICRODESC - Output the first portion of a V3 microdesc
 *        consensus entry.
 *   NS_V3_VOTE - Output a complete V3 NS vote
 *   NS_CONTROL_PORT - Output a NS document for the control port
 */
+34 −14
Original line number Diff line number Diff line
@@ -11,7 +11,9 @@
 * \brief Functions to compute directory consensus, and schedule voting.
 **/

/** DOCDOC*/
/** A consensus that we have built and are appending signatures to.  Once it's
 * time to publish it, it will become an active consensus if it accumulates
 * enough signatures. */
typedef struct pending_consensus_t {
  /** The body of the consensus that we're currently building.  Once we
   * have it built, it goes into dirserv.c */
@@ -264,7 +266,8 @@ get_voter(const networkstatus_t *vote)
  return smartlist_get(vote->voters, 0);
}

/** DOCDOC */
/** Return the signature made by <b>voter</b> using the algorithm
 * <b>alg</b>, or NULL if none is found. */
document_signature_t *
voter_get_sig_by_algorithm(const networkstatus_voter_info_t *voter,
                           digest_algorithm_t alg)
@@ -425,7 +428,8 @@ compute_routerstatus_consensus(smartlist_t *votes, int consensus_method,
        char d[DIGEST256_LEN];
        if (compare_vote_rs(rs, most))
          continue;
        if (!vote_routerstatus_find_microdesc_hash(d, rs, consensus_method))
        if (!vote_routerstatus_find_microdesc_hash(d, rs, consensus_method,
                                                   DIGEST_SHA256))
          smartlist_add(digests, tor_memdup(d, sizeof(d)));
    } SMARTLIST_FOREACH_END(rs);
    smartlist_sort_digests256(digests);
@@ -439,9 +443,9 @@ compute_routerstatus_consensus(smartlist_t *votes, int consensus_method,
  return most;
}

/** Given a list of strings in <b>lst</b>, set the DIGEST_LEN-byte digest at
 * <b>digest_out</b> to the hash of the concatenation of those strings. DOCDOC
 * new arguments. */
/** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest
 * at <b>digest_out</b> to the hash of the concatenation of those strings,
 * computed with the algorithm <b>alg</b>. */
static void
hash_list_members(char *digest_out, size_t len_out,
                  smartlist_t *lst, digest_algorithm_t alg)
@@ -1523,7 +1527,11 @@ networkstatus_add_detached_signatures(networkstatus_t *target,
  return r;
}

/** DOCDOC */
/** Return a newly allocated string containing all the signatures on
 * <b>consensus</b> by all voters. If <b>for_detached_signatures</b> is true,
 * then the signatures will be put in a detached signatures document, so
 * prefix any non-NS-flavored signatures with "additional-signature" rather
 * than "directory-signature". */
static char *
networkstatus_format_signatures(networkstatus_t *consensus,
                                int for_detached_signatures)
@@ -1674,7 +1682,9 @@ networkstatus_get_detached_signatures(smartlist_t *consensuses)
  return result;
}

/** DOCDOC */
/** Return a newly allocated string holding a detached-signatures document for
 * all of the in-progress consensuses in the <b>n_flavors</b>-element array at
 * <b>pending</b>. */
static char *
get_detached_signatures_from_pending_consensuses(pending_consensus_t *pending,
                                                 int n_flavors)
@@ -2049,7 +2059,8 @@ dirvote_fetch_missing_signatures(void)
                                     0, NULL);
}

/** DOCDOC */
/** Release all storage held by pending consensuses (those waiting for
 * signatures). */
static void
dirvote_clear_pending_consensuses(void)
{
@@ -2775,7 +2786,10 @@ dirvote_create_microdescriptor(const routerinfo_t *ri)
/** Cached space-separated string to hold */
static char *microdesc_consensus_methods = NULL;

/** DOCDOC */
/** Format the appropriate vote line to describe the microdescriptor <b>md</b>
 * in a consensus vote document.  Write it into the <b>out_len</b>-byte buffer
 * in <b>out</b>.  Return -1 on failure and the number of characters written
 * on success. */
int
dirvote_format_microdesc_vote_line(char *out, size_t out_len,
                                   const microdesc_t *md)
@@ -2798,19 +2812,25 @@ dirvote_format_microdesc_vote_line(char *out, size_t out_len,
  return strlen(out);
}

/** DOCDOC */
/** If <b>vrs</b> has a hash made for the consensus method <b>method</b> with
 * the digest algorithm <b>alg</b>, decode it and copy it into
 * <b>digest256_out</b> and return 0.  Otherwise return -1. */
int
vote_routerstatus_find_microdesc_hash(char *digest256_out,
                                      const vote_routerstatus_t *vrs,
                                      int method)
                                      int method,
                                      digest_algorithm_t alg)
{
  /* XXXX only returns the sha256 method. */
  const vote_microdesc_hash_t *h;
  char mstr[64];
  size_t mlen;
  char dstr[64];

  tor_snprintf(mstr, sizeof(mstr), "%d", method);
  mlen = strlen(mstr);
  tor_snprintf(dstr, sizeof(dstr), " %s=",
               crypto_digest_algorithm_get_name(alg));

  for (h = vrs->microdesc; h; h = h->next) {
    const char *cp = h->microdesc_hash_line;
@@ -2824,10 +2844,10 @@ vote_routerstatus_find_microdesc_hash(char *digest256_out,
        char buf[BASE64_DIGEST256_LEN+1];
        /* XXXX ignores extraneous stuff if the digest is too long.  This
         * seems harmless enough, right? */
        cp = strstr(cp, " sha256=");
        cp = strstr(cp, dstr);
        if (!cp)
          return -1;
        cp += strlen(" sha256=");
        cp += strlen(dstr);
        strlcpy(buf, cp, sizeof(buf));
        return digest256_from_base64(digest256_out, buf);
      }
+37 −9
Original line number Diff line number Diff line
@@ -3,20 +3,26 @@

#include "or.h"

/** DOCDOC everything here. */

#define MICRODESC_IN_CONSENSUS 1
#define MICRODESC_IN_VOTE 2

/** A data structure to hold a bunch of cached microdescriptors.  There are
 * two active files in the cache: a "cache file" that we mmap, and a "journal
 * file" that we append to.  Periodically, we rebuild the cache file to hold
 * only the microdescriptors that we want to keep */
struct microdesc_cache_t {
  /** Map from sha256-digest to microdesc_t for every microdesc_t in the
   * cache. */
  HT_HEAD(microdesc_map, microdesc_t) map;

  /** Name of the cache file. */
  char *cache_fname;
  /** Name of the journal file. */
  char *journal_fname;
  /** Mmap'd contents of the cache file, or NULL if there is none. */
  tor_mmap_t *cache_content;
  /** Number of bytes used in the journal file. */
  size_t journal_len;
};

/** Helper: computes a hash of <b>md</b> to place it in a hash table. */
static INLINE unsigned int
_microdesc_hash(microdesc_t *md)
{
@@ -28,6 +34,7 @@ _microdesc_hash(microdesc_t *md)
#endif
}

/** Helper: compares <b>a</b> and </b> for equality for hash-table purposes. */
static INLINE int
_microdesc_eq(microdesc_t *a, microdesc_t *b)
{
@@ -40,7 +47,10 @@ HT_GENERATE(microdesc_map, microdesc_t, node,
             _microdesc_hash, _microdesc_eq, 0.6,
             _tor_malloc, _tor_realloc, _tor_free);

/* returns n bytes written */
/** Write the body of <b>md</b> into <b>f</b>, with appropriate annotations.
 * On success, return the total number of bytes written, and set
 * *<b>annotation_len_out</b> to the number of bytes written as
 * annotations. */
static int
dump_microdescriptor(FILE *f, microdesc_t *md, int *annotation_len_out)
{
@@ -64,8 +74,11 @@ dump_microdescriptor(FILE *f, microdesc_t *md, int *annotation_len_out)
  return r;
}

/** Holds a pointer to the current microdesc_cache_t object, or NULL if no
 * such object has been allocated. */
static microdesc_cache_t *the_microdesc_cache = NULL;

/** Return a pointer to the microdescriptor cache, loading it if necessary. */
microdesc_cache_t *
get_microdesc_cache(void)
{
@@ -86,7 +99,12 @@ get_microdesc_cache(void)
   3) Downloaded.
*/

/* Returns list of added microdesc_t. */
/** Decode the microdescriptors from the string starting at <b>s</b> and
 * ending at <b>eos</b>, and store them in <b>cache</b>.  If <b>no-save</b>,
 * mark them as non-writable to disk.  If <b>where</b> is SAVED_IN_CACHE,
 * leave their bodies as pointers to the mmap'd cache.  If where is
 * <b>SAVED_NOWHERE</b>, do not allow annotations.  Return a list of the added
 * microdescriptors.  */
smartlist_t *
microdescs_add_to_cache(microdesc_cache_t *cache,
                        const char *s, const char *eos, saved_location_t where,
@@ -107,8 +125,9 @@ microdescs_add_to_cache(microdesc_cache_t *cache,
  return added;
}

/* Returns list of added microdesc_t. Frees any not added. Updates last_listed.
 */
/* As microdescs_add_to_cache, but takes a list of micrdescriptors instead of
 * a string to encode.  Frees any members of <b>descriptors</b> that it does
 * not add. */
smartlist_t *
microdescs_add_list_to_cache(microdesc_cache_t *cache,
                             smartlist_t *descriptors, saved_location_t where,
@@ -174,6 +193,7 @@ microdescs_add_list_to_cache(microdesc_cache_t *cache,
  return added;
}

/** Remove every microdescriptor in <b>cache</b>. */
void
microdesc_cache_clear(microdesc_cache_t *cache)
{
@@ -190,6 +210,8 @@ microdesc_cache_clear(microdesc_cache_t *cache)
  }
}

/** Reload the contents of <b>cache</b> from disk.  If it is empty, load it
 * for the first time.  Return 0 on success, -1 on failure. */
int
microdesc_cache_reload(microdesc_cache_t *cache)
{
@@ -228,6 +250,9 @@ microdesc_cache_reload(microdesc_cache_t *cache)
  return 0;
}

/** Regenerate the main cache file for <b>cache</b>, clear the journal file,
 * and update every microdesc_t in the cache with pointers to its new
 * location. */
int
microdesc_cache_rebuild(microdesc_cache_t *cache)
{
@@ -298,6 +323,8 @@ microdesc_cache_rebuild(microdesc_cache_t *cache)
  return 0;
}

/** Deallocate a single microdescriptor.  Note: the microdescriptor MUST have
 * previously been removed from the cache if it had ever been inserted. */
void
microdesc_free(microdesc_t *md)
{
@@ -316,6 +343,7 @@ microdesc_free(microdesc_t *md)
  tor_free(md);
}

/** Free all storage held in the microdesc.c module. */
void
microdesc_free_all(void)
{
+2 −1
Original line number Diff line number Diff line
@@ -2082,7 +2082,8 @@ networkstatus_get_flavor_name(consensus_flavor_t flav)
  }
}

/** DOCDOC return -1 on unknown */
/** Return the consensus_flavor_t value for the flavor called <b>flavname</b>,
 * or -1 if the flavor is not recongized. */
int
networkstatus_parse_flavor_name(const char *flavname)
{
Loading