Commit 83c3f118 authored by Nick Mathewson's avatar Nick Mathewson 🥔
Browse files

Code to parse and access network parameters.

Partial backport of 381766ce.
Partial backport of 56c6d785.
parent 95008db0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -119,6 +119,10 @@ typedef unsigned int uint32_t;
#endif
#endif

#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif

#if (SIZEOF_LONG == 4)
#ifndef HAVE_INT32_T
typedef signed long int32_t;
+31 −0
Original line number Diff line number Diff line
@@ -286,6 +286,10 @@ networkstatus_vote_free(networkstatus_t *ns)
    SMARTLIST_FOREACH(ns->known_flags, char *, c, tor_free(c));
    smartlist_free(ns->known_flags);
  }
  if (ns->net_params) {
    SMARTLIST_FOREACH(ns->net_params, char *, c, tor_free(c));
    smartlist_free(ns->net_params);
  }
  if (ns->supported_methods) {
    SMARTLIST_FOREACH(ns->supported_methods, char *, c, tor_free(c));
    smartlist_free(ns->supported_methods);
@@ -1884,6 +1888,33 @@ networkstatus_dump_bridge_status_to_file(time_t now)
  tor_free(status);
}

/** Return the value of a integer parameter from the networkstatus <b>ns</b>
 * whose name is <b>param_name</b>.  Return <b>default_val</b> if ns is NULL,
 * or if it has no parameter called <b>param_name</b>. */
int32_t
networkstatus_get_param(networkstatus_t *ns, const char *param_name,
                        int32_t default_val)
{
  size_t name_len;

  if (!ns || !ns->net_params)
    return default_val;

  name_len = strlen(param_name);

  SMARTLIST_FOREACH_BEGIN(ns->net_params, const char *, p) {
    if (!strcmpstart(p, param_name) && p[name_len] == '=') {
      int ok=0;
      long v = tor_parse_long(p+name_len+1, 10, INT32_MIN, INT32_MAX, &ok,
                              NULL);
      if (ok)
        return (int32_t) v;
    }
  } SMARTLIST_FOREACH_END(p);

  return default_val;
}

/** If <b>question</b> is a string beginning with "ns/" in a format the
 * control interface expects for a GETINFO question, set *<b>answer</b> to a
 * newly-allocated string containing networkstatus lines for the appropriate
+9 −3
Original line number Diff line number Diff line
@@ -1655,6 +1655,10 @@ typedef struct networkstatus_t {
   * not listed here, the voter has no opinion on what its value should be. */
  smartlist_t *known_flags;

  /** List of key=value strings for the parameters in this vote or
   * consensus, sorted by key. */
  smartlist_t *net_params;

  /** List of networkstatus_voter_info_t.  For a vote, only one element
   * is included.  For a consensus, one element is included for every voter
   * whose vote contributed to the consensus. */
@@ -3570,9 +3574,9 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
                                        authority_cert_t *cert);

#ifdef DIRVOTE_PRIVATE
char *
format_networkstatus_vote(crypto_pk_env_t *private_key,
char *format_networkstatus_vote(crypto_pk_env_t *private_key,
                                 networkstatus_t *v3_ns);
char *dirvote_compute_params(smartlist_t *votes);
#endif

/********************************* dns.c ***************************/
@@ -3787,6 +3791,8 @@ void signed_descs_update_status_from_consensus_networkstatus(
char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
char *networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now);
void networkstatus_dump_bridge_status_to_file(time_t now);
int32_t networkstatus_get_param(networkstatus_t *ns, const char *param_name,
                                int32_t default_val);
int getinfo_helper_networkstatus(control_connection_t *conn,
                                 const char *question, char **answer);
void networkstatus_free_all(void);
+31 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ typedef enum {
  K_VOTING_DELAY,

  K_KNOWN_FLAGS,
  K_PARAMS,
  K_VOTE_DIGEST,
  K_CONSENSUS_DIGEST,
  K_CONSENSUS_METHODS,
@@ -383,6 +384,7 @@ static token_rule_t networkstatus_token_table[] = {
  T1("valid-until",            K_VALID_UNTIL,      CONCAT_ARGS, NO_OBJ ),
  T1("voting-delay",           K_VOTING_DELAY,     GE(2),       NO_OBJ ),
  T1("known-flags",            K_KNOWN_FLAGS,      ARGS,        NO_OBJ ),
  T01("params",                K_PARAMS,           ARGS,        NO_OBJ ),
  T( "fingerprint",            K_FINGERPRINT,      CONCAT_ARGS, NO_OBJ ),

  CERTIFICATE_MEMBERS
@@ -420,6 +422,7 @@ static token_rule_t networkstatus_consensus_token_table[] = {
  T01("client-versions",     K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ),
  T01("server-versions",     K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ),
  T01("consensus-method",    K_CONSENSUS_METHOD,    EQ(1),   NO_OBJ),
  T01("params",                K_PARAMS,           ARGS,        NO_OBJ ),

  END_OF_TABLE
};
@@ -2310,6 +2313,34 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
    goto err;
  }

  tok = find_opt_by_keyword(tokens, K_PARAMS);
  if (tok) {
    inorder = 1;
    ns->net_params = smartlist_create();
    for (i = 0; i < tok->n_args; ++i) {
      int ok=0;
      char *eq = strchr(tok->args[i], '=');
      if (!eq) {
        log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
        goto err;
      }
      tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
      if (!ok) {
        log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
        goto err;
      }
      if (i > 0 && strcmp(tok->args[i-1], tok->args[i]) >= 0) {
        log_warn(LD_DIR, "%s >= %s", tok->args[i-1], tok->args[i]);
        inorder = 0;
      }
      smartlist_add(ns->net_params, tor_strdup(tok->args[i]));
    }
    if (!inorder) {
      log_warn(LD_DIR, "params not in order");
      goto err;
    }
  }

  ns->voters = smartlist_create();

  SMARTLIST_FOREACH_BEGIN(tokens, directory_token_t *, _tok) {