summaryrefslogtreecommitdiff
path: root/src/or/routerparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/routerparse.c')
-rw-r--r--src/or/routerparse.c78
1 files changed, 48 insertions, 30 deletions
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 6b6e21d5d0..91025c1568 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -1,7 +1,7 @@
- /* Copyright (c) 2001 Matej Pfajfar.
+/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2015, The Tor Project, Inc. */
+ * Copyright (c) 2007-2016, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -35,8 +35,9 @@
/****************************************************************************/
/** Enumeration of possible token types. The ones starting with K_ correspond
- * to directory 'keywords'. ERR_ is an error in the tokenizing process, EOF_
- * is an end-of-file marker, and NIL_ is used to encode not-a-token.
+ * to directory 'keywords'. A_ is for an annotation, R or C is related to
+ * hidden services, ERR_ is an error in the tokenizing process, EOF_ is an
+ * end-of-file marker, and NIL_ is used to encode not-a-token.
*/
typedef enum {
K_ACCEPT = 0,
@@ -125,6 +126,7 @@ typedef enum {
K_DIR_KEY_CERTIFICATION,
K_DIR_KEY_CROSSCERT,
K_DIR_ADDRESS,
+ K_DIR_TUNNELLED,
K_VOTE_STATUS,
K_VALID_AFTER,
@@ -318,6 +320,7 @@ static token_rule_t routerdesc_token_table[] = {
T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
T1( "bandwidth", K_BANDWIDTH, GE(3), NO_OBJ ),
A01("@purpose", A_PURPOSE, GE(1), NO_OBJ ),
+ T01("tunnelled-dir-server",K_DIR_TUNNELLED, NO_ARGS, NO_OBJ ),
END_OF_TABLE
};
@@ -535,7 +538,7 @@ static int router_get_hash_impl(const char *s, size_t s_len, char *digest,
char end_char,
digest_algorithm_t alg);
static int router_get_hashes_impl(const char *s, size_t s_len,
- digests_t *digests,
+ common_digests_t *digests,
const char *start_str, const char *end_str,
char end_char);
static void token_clear(directory_token_t *tok);
@@ -635,7 +638,7 @@ router_get_router_hash(const char *s, size_t s_len, char *digest)
/** Set <b>digests</b> to all the digests of the consensus document in
* <b>s</b> */
int
-router_get_networkstatus_v3_hashes(const char *s, digests_t *digests)
+router_get_networkstatus_v3_hashes(const char *s, common_digests_t *digests)
{
return router_get_hashes_impl(s,strlen(s),digests,
"network-status-version",
@@ -1402,7 +1405,8 @@ router_parse_entry_from_string(const char *s, const char *end,
log_warn(LD_DIR, "Couldn't parse ed25519 cert");
goto err;
}
- router->signing_key_cert = cert; /* makes sure it gets freed. */
+ /* makes sure it gets freed. */
+ router->cache_info.signing_key_cert = cert;
if (cert->cert_type != CERT_TYPE_ID_SIGNING ||
! cert->signing_key_included) {
@@ -1597,8 +1601,8 @@ router_parse_entry_from_string(const char *s, const char *end,
}
if (tok->n_args >= 2) {
- if (digest256_from_base64(router->extra_info_digest256, tok->args[1])
- < 0) {
+ if (digest256_from_base64(router->cache_info.extra_info_digest256,
+ tok->args[1]) < 0) {
log_warn(LD_DIR, "Invalid extra info digest256 %s",
escaped(tok->args[1]));
}
@@ -1609,6 +1613,12 @@ router_parse_entry_from_string(const char *s, const char *end,
router->wants_to_be_hs_dir = 1;
}
+ /* This router accepts tunnelled directory requests via begindir if it has
+ * an open dirport or it included "tunnelled-dir-server". */
+ if (find_opt_by_keyword(tokens, K_DIR_TUNNELLED) || router->dir_port > 0) {
+ router->supports_tunnelled_dir_requests = 1;
+ }
+
tok = find_by_keyword(tokens, K_ROUTER_SIGNATURE);
note_crypto_pk_op(VERIFY_RTR);
#ifdef COUNT_DISTINCT_DIGESTS
@@ -1777,7 +1787,9 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
log_warn(LD_DIR, "Couldn't parse ed25519 cert");
goto err;
}
- extrainfo->signing_key_cert = cert; /* makes sure it gets freed. */
+ /* makes sure it gets freed. */
+ extrainfo->cache_info.signing_key_cert = cert;
+
if (cert->cert_type != CERT_TYPE_ID_SIGNING ||
! cert->signing_key_included) {
log_warn(LD_DIR, "Invalid form for ed25519 cert");
@@ -2061,7 +2073,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
* object (starting with "r " at the start of a line). If none is found,
* return the start of the directory footer, or the next directory signature.
* If none is found, return the end of the string. */
-static INLINE const char *
+static inline const char *
find_start_of_next_routerstatus(const char *s)
{
const char *eos, *footer, *sig;
@@ -2294,6 +2306,8 @@ routerstatus_parse_entry_from_string(memarea_t *area,
rs->is_unnamed = 1;
} else if (!strcmp(tok->args[i], "HSDir")) {
rs->is_hs_dir = 1;
+ } else if (!strcmp(tok->args[i], "V2Dir")) {
+ rs->is_v2_dir = 1;
}
}
}
@@ -2836,7 +2850,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
smartlist_t *rs_tokens = NULL, *footer_tokens = NULL;
networkstatus_voter_info_t *voter = NULL;
networkstatus_t *ns = NULL;
- digests_t ns_digests;
+ common_digests_t ns_digests;
const char *cert, *end_of_header, *end_of_footer, *s_dup = s;
directory_token_t *tok;
int ok;
@@ -3431,15 +3445,16 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
return ns;
}
-/** Return the digests_t that holds the digests of the
+/** Return the common_digests_t that holds the digests of the
* <b>flavor_name</b>-flavored networkstatus according to the detached
- * signatures document <b>sigs</b>, allocating a new digests_t as neeeded. */
-static digests_t *
+ * signatures document <b>sigs</b>, allocating a new common_digests_t as
+ * neeeded. */
+static common_digests_t *
detached_get_digests(ns_detached_signatures_t *sigs, const char *flavor_name)
{
- digests_t *d = strmap_get(sigs->digests, flavor_name);
+ common_digests_t *d = strmap_get(sigs->digests, flavor_name);
if (!d) {
- d = tor_malloc_zero(sizeof(digests_t));
+ d = tor_malloc_zero(sizeof(common_digests_t));
strmap_set(sigs->digests, flavor_name, d);
}
return d;
@@ -3447,7 +3462,7 @@ detached_get_digests(ns_detached_signatures_t *sigs, const char *flavor_name)
/** Return the list of signatures of the <b>flavor_name</b>-flavored
* networkstatus according to the detached signatures document <b>sigs</b>,
- * allocating a new digests_t as neeeded. */
+ * allocating a new common_digests_t as neeeded. */
static smartlist_t *
detached_get_signatures(ns_detached_signatures_t *sigs,
const char *flavor_name)
@@ -3469,7 +3484,7 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
* networkstatus_parse_vote_from_string(). */
directory_token_t *tok;
memarea_t *area = NULL;
- digests_t *digests;
+ common_digests_t *digests;
smartlist_t *tokens = smartlist_new();
ns_detached_signatures_t *sigs =
@@ -3667,10 +3682,10 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
*
* Returns NULL on policy errors.
*
- * If there is a policy error, malformed_list is set to true if the entire
- * policy list should be discarded. Otherwise, it is set to false, and only
- * this item should be ignored - the rest of the policy list can continue to
- * be processed and used.
+ * Set *<b>malformed_list</b> to true if the entire policy list should be
+ * discarded. Otherwise, set it to false, and only this item should be ignored
+ * on error - the rest of the policy list can continue to be processed and
+ * used.
*
* The addr_policy_t returned by this function can have its address set to
* AF_UNSPEC for '*'. Use policy_expand_unspec() to turn this into a pair
@@ -3683,8 +3698,8 @@ router_parse_addr_policy_item_from_string,(const char *s, int assume_action,
directory_token_t *tok = NULL;
const char *cp, *eos;
/* Longest possible policy is
- * "accept6 ffff:ffff:..255/128:10000-65535",
- * which contains a max-length IPv6 address, plus 24 characters.
+ * "accept6 [ffff:ffff:..255]/128:10000-65535",
+ * which contains a max-length IPv6 address, plus 26 characters.
* But note that there can be an arbitrary amount of space between the
* accept and the address:mask/port element.
* We don't need to multiply TOR_ADDR_BUF_LEN by 2, as there is only one
@@ -3696,9 +3711,12 @@ router_parse_addr_policy_item_from_string,(const char *s, int assume_action,
memarea_t *area = NULL;
tor_assert(malformed_list);
+ *malformed_list = 0;
s = eat_whitespace(s);
- if ((*s == '*' || TOR_ISDIGIT(*s)) && assume_action >= 0) {
+ /* We can only do assume_action on []-quoted IPv6, as "a" (accept)
+ * and ":" (port separator) are ambiguous */
+ if ((*s == '*' || *s == '[' || TOR_ISDIGIT(*s)) && assume_action >= 0) {
if (tor_snprintf(line, sizeof(line), "%s %s",
assume_action == ADDR_POLICY_ACCEPT?"accept":"reject", s)<0) {
log_warn(LD_DIR, "Policy %s is too long.", escaped(s));
@@ -3929,7 +3947,7 @@ token_clear(directory_token_t *tok)
* Return <b>tok</b> on success, or a new ERR_ token if the token didn't
* conform to the syntax we wanted.
**/
-static INLINE directory_token_t *
+static inline directory_token_t *
token_check_object(memarea_t *area, const char *kwd,
directory_token_t *tok, obj_syntax o_syn)
{
@@ -3994,7 +4012,7 @@ token_check_object(memarea_t *area, const char *kwd,
* number of parsed elements into the n_args field of <b>tok</b>. Allocate
* all storage in <b>area</b>. Return the number of arguments parsed, or
* return -1 if there was an insanely high number of arguments. */
-static INLINE int
+static inline int
get_token_arguments(memarea_t *area, directory_token_t *tok,
const char *s, const char *eol)
{
@@ -4429,7 +4447,7 @@ router_get_hash_impl(const char *s, size_t s_len, char *digest,
/** As router_get_hash_impl, but compute all hashes. */
static int
-router_get_hashes_impl(const char *s, size_t s_len, digests_t *digests,
+router_get_hashes_impl(const char *s, size_t s_len, common_digests_t *digests,
const char *start_str,
const char *end_str, char end_c)
{
@@ -4438,7 +4456,7 @@ router_get_hashes_impl(const char *s, size_t s_len, digests_t *digests,
&start,&end)<0)
return -1;
- if (crypto_digest_all(digests, start, end-start)) {
+ if (crypto_common_digests(digests, start, end-start)) {
log_warn(LD_BUG,"couldn't compute digests");
return -1;
}