aboutsummaryrefslogtreecommitdiff
path: root/src/feature/dirparse
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2019-09-09 15:41:24 -0400
committerNick Mathewson <nickm@torproject.org>2019-09-19 14:37:24 -0400
commitec368409fa7732a08e85c1bfb254469f02458266 (patch)
tree4e110fd8974afc78ad7fa261c6e12e0d8abd8dc3 /src/feature/dirparse
parentb1552e8814559fc8bf773765975fa1fded83c391 (diff)
downloadtor-ec368409fa7732a08e85c1bfb254469f02458266.tar.gz
tor-ec368409fa7732a08e85c1bfb254469f02458266.zip
Extract field-parsing code for microdesc_parse.c
The code here parses the fields from the microdescriptor, including possible annotations, and stores them into a microdesc_t object. This commit is almost pure code movement; I recommend using --color-moved to review it.
Diffstat (limited to 'src/feature/dirparse')
-rw-r--r--src/feature/dirparse/microdesc_parse.c143
1 files changed, 83 insertions, 60 deletions
diff --git a/src/feature/dirparse/microdesc_parse.c b/src/feature/dirparse/microdesc_parse.c
index 29bebbed31..5af4c60cb3 100644
--- a/src/feature/dirparse/microdesc_parse.c
+++ b/src/feature/dirparse/microdesc_parse.c
@@ -162,62 +162,27 @@ microdesc_extract_body(microdesc_t *md,
return no_onion_key ? -1 : 0;
}
-/** Parse as many microdescriptors as are found from the string starting at
- * <b>s</b> and ending at <b>eos</b>. If allow_annotations is set, read any
- * annotations we recognize and ignore ones we don't.
- *
- * If <b>saved_location</b> isn't SAVED_IN_CACHE, make a local copy of each
- * descriptor in the body field of each microdesc_t.
+/**
+ * Parse a microdescriptor which begins at <b>s</b> and ends at
+ * <b>start_of_next_microdesc. Store its fields into <b>md</b>. Use
+ * <b>where</b> for generating log information. If <b>allow_annotations</b>
+ * is true, then one or more annotations may precede the microdescriptor body
+ * proper. Use <b>area</b> for memory management, clearing it when done.
*
- * Return all newly parsed microdescriptors in a newly allocated
- * smartlist_t. If <b>invalid_disgests_out</b> is provided, add a SHA256
- * microdesc digest to it for every microdesc that we found to be badly
- * formed. (This may cause duplicates) */
-smartlist_t *
-microdescs_parse_from_string(const char *s, const char *eos,
- int allow_annotations,
- saved_location_t where,
- smartlist_t *invalid_digests_out)
+ * On success, return 0; otherwise return -1.
+ **/
+static int
+microdesc_parse_fields(microdesc_t *md,
+ memarea_t *area,
+ const char *s, const char *start_of_next_microdesc,
+ int allow_annotations,
+ saved_location_t where)
{
- smartlist_t *tokens;
- smartlist_t *result;
- microdesc_t *md = NULL;
- memarea_t *area;
- const char *start = s;
- const char *start_of_next_microdesc;
+ smartlist_t *tokens = smartlist_new();
+ int rv = -1;
int flags = allow_annotations ? TS_ANNOTATIONS_OK : 0;
-
directory_token_t *tok;
- if (!eos)
- eos = s + strlen(s);
-
- s = eat_whitespace_eos(s, eos);
- area = memarea_new();
- result = smartlist_new();
- tokens = smartlist_new();
-
- while (s < eos) {
- int okay = 0;
-
- start_of_next_microdesc = find_start_of_next_microdesc(s, eos);
- if (!start_of_next_microdesc)
- start_of_next_microdesc = eos;
-
- md = tor_malloc_zero(sizeof(microdesc_t));
- uint8_t md_digest[DIGEST256_LEN];
- {
- int body_not_found = microdesc_extract_body(md, start, s,
- start_of_next_microdesc,
- where) < 0;
-
- memcpy(md_digest, md->digest, DIGEST256_LEN);
- if (body_not_found) {
- log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Malformed or truncated descriptor");
- goto next;
- }
- }
-
if (tokenize_string(area, s, start_of_next_microdesc, tokens,
microdesc_token_table, flags)) {
log_warn(LD_DIR, "Unparseable microdescriptor found in %s",
@@ -301,10 +266,74 @@ microdescs_parse_from_string(const char *s, const char *eos,
md->policy_is_reject_star = 1;
}
- smartlist_add(result, md);
- okay = 1;
+ rv = 0;
+ next: // todo: rename this label.
+
+ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
+ memarea_clear(area);
+ smartlist_free(tokens);
+
+ return rv;
+}
+
+/** Parse as many microdescriptors as are found from the string starting at
+ * <b>s</b> and ending at <b>eos</b>. If allow_annotations is set, read any
+ * annotations we recognize and ignore ones we don't.
+ *
+ * If <b>saved_location</b> isn't SAVED_IN_CACHE, make a local copy of each
+ * descriptor in the body field of each microdesc_t.
+ *
+ * Return all newly parsed microdescriptors in a newly allocated
+ * smartlist_t. If <b>invalid_disgests_out</b> is provided, add a SHA256
+ * microdesc digest to it for every microdesc that we found to be badly
+ * formed. (This may cause duplicates) */
+smartlist_t *
+microdescs_parse_from_string(const char *s, const char *eos,
+ int allow_annotations,
+ saved_location_t where,
+ smartlist_t *invalid_digests_out)
+{
+ smartlist_t *result;
+ microdesc_t *md = NULL;
+ memarea_t *area;
+ const char *start = s;
+ const char *start_of_next_microdesc;
+
+ if (!eos)
+ eos = s + strlen(s);
+
+ s = eat_whitespace_eos(s, eos);
+ area = memarea_new();
+ result = smartlist_new();
+
+ while (s < eos) {
+ int okay = 0;
+
+ start_of_next_microdesc = find_start_of_next_microdesc(s, eos);
+ if (!start_of_next_microdesc)
+ start_of_next_microdesc = eos;
+
+ md = tor_malloc_zero(sizeof(microdesc_t));
+ uint8_t md_digest[DIGEST256_LEN];
+ {
+ int body_not_found = microdesc_extract_body(md, start, s,
+ start_of_next_microdesc,
+ where) < 0;
+
+ memcpy(md_digest, md->digest, DIGEST256_LEN);
+ if (body_not_found) {
+ log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Malformed or truncated descriptor");
+ goto next;
+ }
+ }
+
+ if (microdesc_parse_fields(md, area, s, start_of_next_microdesc,
+ allow_annotations, where) == 0) {
+ smartlist_add(result, md);
+ md = NULL; // prevent free
+ okay = 1;
+ }
- md = NULL;
next:
if (! okay && invalid_digests_out) {
smartlist_add(invalid_digests_out,
@@ -312,16 +341,10 @@ microdescs_parse_from_string(const char *s, const char *eos,
}
microdesc_free(md);
md = NULL;
-
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
- memarea_clear(area);
- smartlist_clear(tokens);
s = start_of_next_microdesc;
}
- SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
memarea_drop_all(area);
- smartlist_free(tokens);
return result;
}