Merge branch 'tor-github/pr/671'

This commit is contained in:
David Goulet 2019-02-12 13:02:30 -05:00
commit 95e5f8fe03
2 changed files with 61 additions and 32 deletions

8
changes/ticket28614 Normal file
View File

@ -0,0 +1,8 @@
o Major bugfixes (windows, startup):
- When writing a consensus file to disk, always write in
"binary" mode so that we can safely map it into memory later.
Fixes part of bug 28614; bugfix on 0.4.0.1-alpha.
- When reading a consensus file from disk, detect whether it
was written in text mode, and re-read it in text mode if it
Fixes part of bug 28614; bugfix on 0.4.0.1-alpha.

View File

@ -178,6 +178,10 @@ static void update_consensus_bootstrap_multiple_downloads(
static int networkstatus_check_required_protocols(const networkstatus_t *ns, static int networkstatus_check_required_protocols(const networkstatus_t *ns,
int client_mode, int client_mode,
char **warning_out); char **warning_out);
static int reload_consensus_from_file(const char *fname,
const char *flavor,
unsigned flags,
const char *source_dir);
/** Forget that we've warned about anything networkstatus-related, so we will /** Forget that we've warned about anything networkstatus-related, so we will
* give fresh warnings if the same behavior happens again. */ * give fresh warnings if the same behavior happens again. */
@ -269,27 +273,15 @@ router_reload_consensus_networkstatus(void)
/* FFFF Suppress warnings if cached consensus is bad? */ /* FFFF Suppress warnings if cached consensus is bad? */
for (flav = 0; flav < N_CONSENSUS_FLAVORS; ++flav) { for (flav = 0; flav < N_CONSENSUS_FLAVORS; ++flav) {
const char *flavor = networkstatus_get_flavor_name(flav); const char *flavor = networkstatus_get_flavor_name(flav);
tor_mmap_t *m = networkstatus_map_cached_consensus_impl(flav, flavor, 0); char *fname = networkstatus_get_cache_fname(flav, flavor, 0);
if (m) { reload_consensus_from_file(fname, flavor, flags, NULL);
if (networkstatus_set_current_consensus(m->data, m->size, tor_free(fname);
flavor, flags, NULL) < -1) {
log_warn(LD_FS, "Couldn't load consensus %s networkstatus from cache",
flavor);
}
tor_munmap_file(m);
}
m = networkstatus_map_cached_consensus_impl(flav, flavor, 1); fname = networkstatus_get_cache_fname(flav, flavor, 1);
if (m) { reload_consensus_from_file(fname, flavor,
if (networkstatus_set_current_consensus(m->data, m->size, flags | NSSET_WAS_WAITING_FOR_CERTS,
flavor, NULL);
flags | NSSET_WAS_WAITING_FOR_CERTS, tor_free(fname);
NULL)) {
log_info(LD_FS, "Couldn't load unverified consensus %s networkstatus "
"from cache", flavor);
}
tor_munmap_file(m);
}
} }
update_certificate_downloads(time(NULL)); update_certificate_downloads(time(NULL));
@ -1750,6 +1742,41 @@ networkstatus_set_current_consensus_from_ns(networkstatus_t *c,
} }
#endif /* defined(TOR_UNIT_TESTS) */ #endif /* defined(TOR_UNIT_TESTS) */
/**
* Helper: Read a the current consensus of type <b>flavor</b> from
* <b>fname</b>. Flags and return values are as for
* networkstatus_set_current_consensus().
**/
static int
reload_consensus_from_file(const char *fname,
const char *flavor,
unsigned flags,
const char *source_dir)
{
tor_mmap_t *map = tor_mmap_file(fname);
if (!map)
return 0;
int rv = networkstatus_set_current_consensus(map->data, map->size,
flavor, flags, source_dir);
#ifdef _WIN32
if (rv < 0 && tor_memstr(map->data, map->size, "\r\n")) {
log_info(LD_GENERAL, "Found CRLF in consensus file %s; falling back to "
"read_file_to_string.", escaped(fname));
char *content = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
rv = networkstatus_set_current_consensus(content, strlen(content),
flavor, flags, source_dir);
tor_free(content);
}
#endif
if (rv < -1) {
log_warn(LD_GENERAL, "Couldn't set consensus from cache file %s",
escaped(fname));
}
tor_munmap_file(map);
return rv;
}
/** /**
* Helper for handle_missing_protocol_warning: handles either the * Helper for handle_missing_protocol_warning: handles either the
* client case (if <b>is_client</b> is set) or the server case otherwise. * client case (if <b>is_client</b> is set) or the server case otherwise.
@ -1991,7 +2018,7 @@ networkstatus_set_current_consensus(const char *consensus,
waiting->set_at = now; waiting->set_at = now;
waiting->dl_failed = 0; waiting->dl_failed = 0;
if (!from_cache) { if (!from_cache) {
write_bytes_to_file(unverified_fname, consensus, consensus_len, 0); write_bytes_to_file(unverified_fname, consensus, consensus_len, 1);
} }
if (dl_certs) if (dl_certs)
authority_certs_fetch_missing(c, now, source_dir); authority_certs_fetch_missing(c, now, source_dir);
@ -2142,7 +2169,7 @@ networkstatus_set_current_consensus(const char *consensus,
} }
if (!from_cache) { if (!from_cache) {
write_bytes_to_file(consensus_fname, consensus, consensus_len, 0); write_bytes_to_file(consensus_fname, consensus, consensus_len, 1);
} }
warn_early_consensus(c, flavor, now); warn_early_consensus(c, flavor, now);
@ -2178,16 +2205,10 @@ networkstatus_note_certs_arrived(const char *source_dir)
if (!waiting->consensus) if (!waiting->consensus)
continue; continue;
if (networkstatus_check_consensus_signature(waiting->consensus, 0)>=0) { if (networkstatus_check_consensus_signature(waiting->consensus, 0)>=0) {
tor_mmap_t *mapping = networkstatus_map_cached_consensus_impl( char *fname = networkstatus_get_cache_fname(i, flavor_name, 1);
i, flavor_name, 1); reload_consensus_from_file(fname, flavor_name,
if (mapping) { NSSET_WAS_WAITING_FOR_CERTS, source_dir);
networkstatus_set_current_consensus(mapping->data, tor_free(fname);
mapping->size,
flavor_name,
NSSET_WAS_WAITING_FOR_CERTS,
source_dir);
}
tor_munmap_file(mapping);
} }
} }
} }