Code to parse and access network parameters.

Partial backport of 381766ce4b.
Partial backport of 56c6d78520.
This commit is contained in:
Nick Mathewson 2009-10-14 16:15:41 -04:00
parent 95008db08d
commit 83c3f118db
4 changed files with 75 additions and 3 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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) {