From 4ec5e139c8442b321ef9b58684da547ea0388261 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 22 May 2007 02:20:52 +0000 Subject: [PATCH] r12850@catbus: nickm | 2007-05-21 22:20:42 -0400 Partial backport candidate: do not rely on finding a \0 after an mmaped() router/extrainfo file. Also, set journal length correctly when starting up. svn:r10248 --- src/common/compat.h | 7 +++++++ src/common/util.c | 29 +++++++++++++++++++++++++++++ src/common/util.h | 1 + src/or/directory.c | 4 ++-- src/or/dirserv.c | 4 ++-- src/or/or.h | 6 +++--- src/or/routerlist.c | 21 ++++++++++++--------- src/or/routerparse.c | 21 +++++++++++++++------ 8 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/common/compat.h b/src/common/compat.h index e5862f982a..085af036d1 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -161,6 +161,13 @@ int tor_vsnprintf(char *str, size_t size, const char *format, va_list args) const void *tor_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen) ATTR_PURE ATTR_NONNULL((1,3)); +static const void *tor_memstr(const void *haystack, size_t hlen, + const char *needle) ATTR_PURE ATTR_NONNULL((1,3)); +static INLINE const void * +tor_memstr(const void *haystack, size_t hlen, const char *needle) +{ + return tor_memmem(haystack, hlen, needle, strlen(needle)); +} #define TOR_ISALPHA(c) isalpha((int)(unsigned char)(c)) #define TOR_ISALNUM(c) isalnum((int)(unsigned char)(c)) diff --git a/src/common/util.c b/src/common/util.c index 0c420f4602..18d9fcba2c 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -418,6 +418,35 @@ eat_whitespace(const char *s) } } +/** Return a pointer to the first char of s that is not whitespace and + * not a comment, or to the terminating NUL if no such character exists. + */ +const char * +eat_whitespace_eos(const char *s, const char *eos) +{ + tor_assert(s); + tor_assert(eos && s <= eos); + + while (s < eos) { + switch (*s) { + case '\0': + default: + return s; + case ' ': + case '\t': + case '\n': + case '\r': + ++s; + break; + case '#': + ++s; + while (s < eos && *s && *s != '\n') + ++s; + } + } + return s; +} + /** Return a pointer to the first char of s that is not a space or a tab, * or to the terminating NUL if no such character exists. */ const char * diff --git a/src/common/util.h b/src/common/util.h index 7a0335935b..6b32708c5e 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -167,6 +167,7 @@ uint64_t tor_parse_uint64(const char *s, int base, uint64_t min, uint64_t max, int *ok, char **next); const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1)); const char *eat_whitespace(const char *s) ATTR_PURE; +const char *eat_whitespace_eos(const char *s, const char *eos) ATTR_PURE; const char *eat_whitespace_no_nl(const char *s) ATTR_PURE; const char *find_whitespace(const char *s) ATTR_PURE; int tor_mem_is_zero(const char *mem, size_t len) ATTR_PURE; diff --git a/src/or/directory.c b/src/or/directory.c index da82a5a92c..7f464acf3c 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -1248,9 +1248,9 @@ connection_dir_client_reached_eof(dir_connection_t *conn) !strcmpstart(conn->requested_resource, "all"))) { /* as we learn from them, we remove them from 'which' */ if (was_ei) { - router_load_extrainfo_from_string(body, SAVED_NOWHERE, which); + router_load_extrainfo_from_string(body, NULL, SAVED_NOWHERE, which); } else { - router_load_routers_from_string(body, SAVED_NOWHERE, which); + router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which); directory_info_has_arrived(now, 0); } } diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 03bf5b1924..fbe09ed25f 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -529,7 +529,7 @@ dirserv_add_multiple_descriptors(const char *desc, const char **msg) s = desc; list = smartlist_create(); - if (!router_parse_list_from_string(&s, list, SAVED_NOWHERE, 0)) { + if (!router_parse_list_from_string(&s, NULL, list, SAVED_NOWHERE, 0)) { SMARTLIST_FOREACH(list, routerinfo_t *, ri, { r_tmp = dirserv_add_descriptor(ri, &msg_out); if (r_tmp < r) { @@ -542,7 +542,7 @@ dirserv_add_multiple_descriptors(const char *desc, const char **msg) smartlist_clear(list); s = desc; - if (!router_parse_list_from_string(&s, list, SAVED_NOWHERE, 1)) { + if (!router_parse_list_from_string(&s, NULL, list, SAVED_NOWHERE, 1)) { SMARTLIST_FOREACH(list, extrainfo_t *, ei, { r_tmp = dirserv_add_extrainfo(ei, &msg_out); if (r_tmp < r) { diff --git a/src/or/or.h b/src/or/or.h index 8f0cb4859e..f595dbd161 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3143,10 +3143,10 @@ void router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg, int from_cache, int from_fetch); int router_load_single_router(const char *s, uint8_t purpose, const char **msg); -void router_load_routers_from_string(const char *s, +void router_load_routers_from_string(const char *s, const char *eos, saved_location_t saved_location, smartlist_t *requested_fingerprints); -void router_load_extrainfo_from_string(const char *s, +void router_load_extrainfo_from_string(const char *s, const char *eos, saved_location_t saved_location, smartlist_t *requested_fps); @@ -3246,7 +3246,7 @@ int router_get_extrainfo_hash(const char *s, char *digest); int router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest, crypto_pk_env_t *private_key); -int router_parse_list_from_string(const char **s, +int router_parse_list_from_string(const char **s, const char *eos, smartlist_t *dest, saved_location_t saved_location, int is_extrainfo); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index e0944a9d53..c5c7c21abd 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -393,7 +393,6 @@ router_rebuild_store(int force, int extrainfo) write_str_to_file(fname, "", 1); r = 0; - tor_assert(offset >= 0); stats->store_len = (size_t) offset; stats->journal_len = 0; stats->bytes_dropped = 0; @@ -420,6 +419,7 @@ router_reload_router_list_impl(int extrainfo) const char *fname_base = extrainfo ? "cached-extrainfo" : "cached-routers"; tor_mmap_t **mmap_ptr; + struct stat st; routerlist_check_bug_417(); @@ -443,21 +443,24 @@ router_reload_router_list_impl(int extrainfo) stats->store_len = (*mmap_ptr)->size; if (extrainfo) router_load_extrainfo_from_string((*mmap_ptr)->data, + (*mmap_ptr)->data+(*mmap_ptr)->size, SAVED_IN_CACHE, NULL); else router_load_routers_from_string((*mmap_ptr)->data, + (*mmap_ptr)->data+(*mmap_ptr)->size, SAVED_IN_CACHE, NULL); } tor_snprintf(fname, fname_len, "%s"PATH_SEPARATOR"%s.new", options->DataDirectory, fname_base); if (file_status(fname) == FN_FILE) - contents = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, NULL); + contents = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st); if (contents) { if (extrainfo) - router_load_extrainfo_from_string(contents, SAVED_IN_JOURNAL, NULL); + router_load_extrainfo_from_string(contents, NULL,SAVED_IN_JOURNAL, NULL); else - router_load_routers_from_string(contents, SAVED_IN_JOURNAL, NULL); + router_load_routers_from_string(contents, NULL, SAVED_IN_JOURNAL, NULL); + stats->journal_len = st.st_size; tor_free(contents); } @@ -823,7 +826,6 @@ routerlist_add_family(smartlist_t *sl, routerinfo_t *router) if (options->EnforceDistinctSubnets) routerlist_add_network_family(sl, router); - if (router->declared_family) { /* Add every r such that router declares familyness with r, and r * declares familyhood with router. */ @@ -2655,7 +2657,8 @@ router_load_single_router(const char *s, uint8_t purpose, const char **msg) * fingerprint from the list. */ void -router_load_routers_from_string(const char *s, saved_location_t saved_location, +router_load_routers_from_string(const char *s, const char *eos, + saved_location_t saved_location, smartlist_t *requested_fingerprints) { smartlist_t *routers = smartlist_create(), *changed = smartlist_create(); @@ -2663,7 +2666,7 @@ router_load_routers_from_string(const char *s, saved_location_t saved_location, const char *msg; int from_cache = (saved_location != SAVED_NOWHERE); - router_parse_list_from_string(&s, routers, saved_location, 0); + router_parse_list_from_string(&s, eos, routers, saved_location, 0); routers_update_status_from_networkstatus(routers, !from_cache); @@ -2705,7 +2708,7 @@ router_load_routers_from_string(const char *s, saved_location_t saved_location, /** DOCDOC */ void -router_load_extrainfo_from_string(const char *s, +router_load_extrainfo_from_string(const char *s, const char *eos, saved_location_t saved_location, smartlist_t *requested_fingerprints) { @@ -2713,7 +2716,7 @@ router_load_extrainfo_from_string(const char *s, const char *msg; int from_cache = (saved_location != SAVED_NOWHERE); - router_parse_list_from_string(&s, extrainfo_list, saved_location, 1); + router_parse_list_from_string(&s, eos, extrainfo_list, saved_location, 1); log_info(LD_DIR, "%d elements to add", smartlist_len(extrainfo_list)); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 6993158175..f590eec1b1 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -831,7 +831,8 @@ check_signature_token(const char *digest, * Returns 0 on success and -1 on failure. */ int -router_parse_list_from_string(const char **s, smartlist_t *dest, +router_parse_list_from_string(const char **s, const char *eos, + smartlist_t *dest, saved_location_t saved_location, int want_extrainfo) { @@ -847,8 +848,16 @@ router_parse_list_from_string(const char **s, smartlist_t *dest, tor_assert(dest); start = *s; + if (!eos) + eos = *s + strlen(*s); + + tor_assert(eos >= *s); + while (1) { - *s = eat_whitespace(*s); + *s = eat_whitespace_eos(*s, eos); + if ((eos - *s) < 32) /* make sure it's long enough. */ + break; + /* Don't start parsing the rest of *s unless it contains a router. */ if (strcmpstart(*s, "extra-info ")==0) { have_extrainfo = 1; @@ -856,8 +865,8 @@ router_parse_list_from_string(const char **s, smartlist_t *dest, have_extrainfo = 0; } else { /* skip junk. */ - const char *ei = strstr(*s, "\nextra-info "); - const char *ri = strstr(*s, "\nrouter "); + const char *ei = tor_memstr(*s, eos-*s, "\nextra-info "); + const char *ri = tor_memstr(*s, eos-*s, "\nrouter "); if (ri && (!ei || ri < ei)) { have_extrainfo = 0; *s = ri + 1; @@ -868,9 +877,9 @@ router_parse_list_from_string(const char **s, smartlist_t *dest, break; } } - end = strstr(*s, "\nrouter-signature"); + end = tor_memstr(*s, eos-*s, "\nrouter-signature"); if (end) - end = strstr(end, "\n-----END SIGNATURE-----\n"); + end = tor_memstr(end, eos-*s, "\n-----END SIGNATURE-----\n"); if (end) end += strlen("\n-----END SIGNATURE-----\n");