[or-cvs] [tor/master] Code to parse and access network parameters.

Nick Mathewson nickm at seul.org
Wed Oct 14 21:22:20 UTC 2009


Author: Nick Mathewson <nickm at torproject.org>
Date: Wed, 14 Oct 2009 16:15:41 -0400
Subject: Code to parse and access network parameters.
Commit: 83c3f118db0ae3911ea72403856df9fb08b2d0e5

Partial backport of 381766ce4b1145460.
Partial backport of 56c6d78520a98fb64.
---
 src/common/torint.h    |    4 ++++
 src/or/networkstatus.c |   31 +++++++++++++++++++++++++++++++
 src/or/or.h            |   12 +++++++++---
 src/or/routerparse.c   |   31 +++++++++++++++++++++++++++++++
 4 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/src/common/torint.h b/src/common/torint.h
index 1f74211..f844185 100644
--- a/src/common/torint.h
+++ b/src/common/torint.h
@@ -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;
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 573197a..05da73b 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -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
diff --git a/src/or/or.h b/src/or/or.h
index 319b3a9..0c0d8e8 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -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,
-                          networkstatus_t *v3_ns);
+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);
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 189458e..4e1d0cd 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -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) {
-- 
1.5.6.5




More information about the tor-commits mailing list