Merge branch 'tor-gitlab/mr/392' into maint-0.4.5

This commit is contained in:
David Goulet 2021-10-06 15:45:13 -04:00
commit adcb094cb6
3 changed files with 33 additions and 25 deletions

5
changes/bug40375 Normal file
View File

@ -0,0 +1,5 @@
o Minor bugfixes (consensus handling):
- Avoid a set of bugs that could be caused by inconsistently preferring
an out-of-date consensus stored in a stale directory cache over
a more recent one stored on disk as the latest consensus.
Fixes bug 40375; bugfix on 0.3.1.1-alpha.

View File

@ -353,26 +353,24 @@ getinfo_helper_current_consensus(consensus_flavor_t flavor,
*errmsg = "Internal error: unrecognized flavor name."; *errmsg = "Internal error: unrecognized flavor name.";
return -1; return -1;
} }
if (we_want_to_fetch_flavor(get_options(), flavor)) {
/** Check from the cache */
const cached_dir_t *consensus = dirserv_get_consensus(flavor_name);
if (consensus) {
*answer = tor_strdup(consensus->dir);
}
}
if (!*answer) { /* try loading it from disk */
tor_mmap_t *mapped = networkstatus_map_cached_consensus(flavor_name); tor_mmap_t *mapped = networkstatus_map_cached_consensus(flavor_name);
if (mapped) { if (mapped) {
*answer = tor_memdup_nulterm(mapped->data, mapped->size); *answer = tor_memdup_nulterm(mapped->data, mapped->size);
tor_munmap_file(mapped); tor_munmap_file(mapped);
} }
if (!*answer) { /* Maybe it's in the cache? */
if (we_want_to_fetch_flavor(get_options(), flavor)) {
const cached_dir_t *consensus = dirserv_get_consensus(flavor_name);
if (consensus) {
*answer = tor_strdup(consensus->dir);
}
}
}
if (!*answer) { /* generate an error */ if (!*answer) { /* generate an error */
*errmsg = "Could not open cached consensus. " *errmsg = "Could not open cached consensus. "
"Make sure FetchUselessDescriptors is set to 1."; "Make sure FetchUselessDescriptors is set to 1.";
return -1; return -1;
} }
}
return 0; return 0;
} }

View File

@ -2280,18 +2280,23 @@ handle_response_fetch_consensus(dir_connection_t *conn,
if (looks_like_a_consensus_diff(body, body_len)) { if (looks_like_a_consensus_diff(body, body_len)) {
/* First find our previous consensus. Maybe it's in ram, maybe not. */ /* First find our previous consensus. Maybe it's in ram, maybe not. */
cached_dir_t *cd = dirserv_get_consensus(flavname); cached_dir_t *cd = NULL;
const char *consensus_body = NULL; const char *consensus_body = NULL;
size_t consensus_body_len; size_t consensus_body_len;
tor_mmap_t *mapped_consensus = NULL; tor_mmap_t *mapped_consensus = NULL;
if (cd) {
consensus_body = cd->dir; /* We prefer the mmap'd version over the cached_dir_t version,
consensus_body_len = cd->dir_len; * since that matches the logic we used when we picked a consensus
} else { * back in dir_consensus_request_set_additional_headers. */
mapped_consensus = networkstatus_map_cached_consensus(flavname); mapped_consensus = networkstatus_map_cached_consensus(flavname);
if (mapped_consensus) { if (mapped_consensus) {
consensus_body = mapped_consensus->data; consensus_body = mapped_consensus->data;
consensus_body_len = mapped_consensus->size; consensus_body_len = mapped_consensus->size;
} else {
cd = dirserv_get_consensus(flavname);
if (cd) {
consensus_body = cd->dir;
consensus_body_len = cd->dir_len;
} }
} }
if (!consensus_body) { if (!consensus_body) {