commit 7bf0587ef1c25d739a8eadf9b747d3a68c99ff51 Author: Florentin Rochet florentin.rochet@uclouvain.be Date: Wed Apr 22 20:36:16 2020 +0200
Refactor some guard state file parsing code into functions.
Co-authored-by: Florentin Rochet florentin.rochet@uclouvain.be --- src/feature/client/entrynodes.c | 128 +++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 55 deletions(-)
diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c index ded7db969..3d2abd920 100644 --- a/src/feature/client/entrynodes.c +++ b/src/feature/client/entrynodes.c @@ -2861,6 +2861,76 @@ entry_guard_encode_for_state(entry_guard_t *guard) }
/** + * Extract key=val from the state string <b>s</s> and duplicate the value to + * some string target declared in entry_guard_parse_from_state + */ +static void parse_from_state_set_vals(const char *s, smartlist_t *entries, + smartlist_t *extra, strmap_t *vals) +{ + smartlist_split_string(entries, s, " ", + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); + + SMARTLIST_FOREACH_BEGIN(entries, char *, entry) { + const char *eq = strchr(entry, '='); + if (!eq) { + smartlist_add(extra, entry); + continue; + } + char *key = tor_strndup(entry, eq-entry); + char **target = strmap_get(vals, key); + if (target == NULL || *target != NULL) { + /* unrecognized or already set */ + smartlist_add(extra, entry); + tor_free(key); + continue; + } + + *target = tor_strdup(eq+1); + tor_free(key); + tor_free(entry); + } SMARTLIST_FOREACH_END(entry); +} + +/** + * Handle part of the parsing state file logic, focused on time related things + */ +static void parse_from_state_handle_time(entry_guard_t *guard, char *sampled_on, + char *unlisted_since, char *confirmed_on) +{ +#define HANDLE_TIME(field) do { \ + if (field) { \ + int r = parse_iso_time_nospace(field, &field ## _time); \ + if (r < 0) { \ + log_warn(LD_CIRC, "Unable to parse %s %s from guard", \ + #field, escaped(field)); \ + field##_time = -1; \ + } \ + } \ + } while (0) + + time_t sampled_on_time = 0; + time_t unlisted_since_time = 0; + time_t confirmed_on_time = 0; + + HANDLE_TIME(sampled_on); + HANDLE_TIME(unlisted_since); + HANDLE_TIME(confirmed_on); + + if (sampled_on_time <= 0) + sampled_on_time = approx_time(); + if (unlisted_since_time < 0) + unlisted_since_time = 0; + if (confirmed_on_time < 0) + confirmed_on_time = 0; + + #undef HANDLE_TIME + + guard->sampled_on_date = sampled_on_time; + guard->unlisted_since_date = unlisted_since_time; + guard->confirmed_on_date = confirmed_on_time; +} + +/** * Given a string generated by entry_guard_encode_for_state(), parse it * (if possible) and return an entry_guard_t object for it. Return NULL * on complete failure. @@ -2920,29 +2990,8 @@ entry_guard_parse_from_state(const char *s) FIELD(pb_unusable_circuits); FIELD(pb_timeouts); #undef FIELD - - smartlist_split_string(entries, s, " ", - SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); - - SMARTLIST_FOREACH_BEGIN(entries, char *, entry) { - const char *eq = strchr(entry, '='); - if (!eq) { - smartlist_add(extra, entry); - continue; - } - char *key = tor_strndup(entry, eq-entry); - char **target = strmap_get(vals, key); - if (target == NULL || *target != NULL) { - /* unrecognized or already set */ - smartlist_add(extra, entry); - tor_free(key); - continue; - } - - *target = tor_strdup(eq+1); - tor_free(key); - tor_free(entry); - } SMARTLIST_FOREACH_END(entry); + /* Extract from s the key=val that we recognize, put the others in extra*/ + parse_from_state_set_vals(s, entries, extra, vals);
smartlist_free(entries); strmap_free(vals, NULL); @@ -2990,38 +3039,7 @@ entry_guard_parse_from_state(const char *s) }
/* Process the various time fields. */ - -#define HANDLE_TIME(field) do { \ - if (field) { \ - int r = parse_iso_time_nospace(field, &field ## _time); \ - if (r < 0) { \ - log_warn(LD_CIRC, "Unable to parse %s %s from guard", \ - #field, escaped(field)); \ - field##_time = -1; \ - } \ - } \ - } while (0) - - time_t sampled_on_time = 0; - time_t unlisted_since_time = 0; - time_t confirmed_on_time = 0; - - HANDLE_TIME(sampled_on); - HANDLE_TIME(unlisted_since); - HANDLE_TIME(confirmed_on); - - if (sampled_on_time <= 0) - sampled_on_time = approx_time(); - if (unlisted_since_time < 0) - unlisted_since_time = 0; - if (confirmed_on_time < 0) - confirmed_on_time = 0; - - #undef HANDLE_TIME - - guard->sampled_on_date = sampled_on_time; - guard->unlisted_since_date = unlisted_since_time; - guard->confirmed_on_date = confirmed_on_time; + parse_from_state_handle_time(guard, sampled_on, unlisted_since, confirmed_on);
/* Take sampled_by_version verbatim. */ guard->sampled_by_version = sampled_by;