Refactor some guard state file parsing code into functions.

Co-authored-by: Florentin Rochet <florentin.rochet@uclouvain.be>
This commit is contained in:
Florentin Rochet 2020-04-22 20:36:16 +02:00 committed by George Kadianakis
parent fc16dbf7aa
commit 7bf0587ef1

View File

@ -2860,6 +2860,76 @@ entry_guard_encode_for_state(entry_guard_t *guard)
return joined; return joined;
} }
/**
* 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 * 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 * (if possible) and return an entry_guard_t object for it. Return NULL
@ -2920,29 +2990,8 @@ entry_guard_parse_from_state(const char *s)
FIELD(pb_unusable_circuits); FIELD(pb_unusable_circuits);
FIELD(pb_timeouts); FIELD(pb_timeouts);
#undef FIELD #undef FIELD
/* Extract from s the key=val that we recognize, put the others in extra*/
smartlist_split_string(entries, s, " ", parse_from_state_set_vals(s, entries, extra, vals);
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);
smartlist_free(entries); smartlist_free(entries);
strmap_free(vals, NULL); strmap_free(vals, NULL);
@ -2990,38 +3039,7 @@ entry_guard_parse_from_state(const char *s)
} }
/* Process the various time fields. */ /* Process the various time fields. */
parse_from_state_handle_time(guard, sampled_on, unlisted_since, 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;
/* Take sampled_by_version verbatim. */ /* Take sampled_by_version verbatim. */
guard->sampled_by_version = sampled_by; guard->sampled_by_version = sampled_by;