mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 20:33:31 +01:00
Fix bug 236: caches should cache up to 16 unrecognized network-status docs.
svn:r5754
This commit is contained in:
parent
1616cb9297
commit
e30516f33f
@ -17,6 +17,9 @@ const char dirserv_c_id[] =
|
|||||||
#define ROUTER_ALLOW_SKEW (60*60*12) /* 12 hours */
|
#define ROUTER_ALLOW_SKEW (60*60*12) /* 12 hours */
|
||||||
/** How many seconds do we wait before regenerating the directory? */
|
/** How many seconds do we wait before regenerating the directory? */
|
||||||
#define DIR_REGEN_SLACK_TIME 30
|
#define DIR_REGEN_SLACK_TIME 30
|
||||||
|
/** If we're a cache, keep this many networkstatuses around from non-trusted
|
||||||
|
* directory authorities. */
|
||||||
|
#define MAX_UNTRUSTED_NETWORKSTATUSES 16
|
||||||
|
|
||||||
extern long stats_n_seconds_working;
|
extern long stats_n_seconds_working;
|
||||||
|
|
||||||
@ -984,28 +987,60 @@ dirserv_set_cached_directory(const char *directory, time_t published,
|
|||||||
* the cache.
|
* the cache.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
dirserv_set_cached_networkstatus_v2(const char *directory,
|
dirserv_set_cached_networkstatus_v2(const char *networkstatus,
|
||||||
const char *identity,
|
const char *identity,
|
||||||
time_t published)
|
time_t published)
|
||||||
{
|
{
|
||||||
cached_dir_t *d;
|
cached_dir_t *d;
|
||||||
|
smartlist_t *trusted_dirs;
|
||||||
if (!cached_v2_networkstatus)
|
if (!cached_v2_networkstatus)
|
||||||
cached_v2_networkstatus = digestmap_new();
|
cached_v2_networkstatus = digestmap_new();
|
||||||
|
|
||||||
if (!(d = digestmap_get(cached_v2_networkstatus, identity))) {
|
if (!(d = digestmap_get(cached_v2_networkstatus, identity))) {
|
||||||
if (!directory)
|
if (!networkstatus)
|
||||||
return;
|
return;
|
||||||
d = tor_malloc_zero(sizeof(cached_dir_t));
|
d = tor_malloc_zero(sizeof(cached_dir_t));
|
||||||
digestmap_set(cached_v2_networkstatus, identity, d);
|
digestmap_set(cached_v2_networkstatus, identity, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
tor_assert(d);
|
tor_assert(d);
|
||||||
if (directory) {
|
if (networkstatus) {
|
||||||
set_cached_dir(d, tor_strdup(directory), published);
|
if (published > d->published) {
|
||||||
|
set_cached_dir(d, tor_strdup(networkstatus), published);
|
||||||
|
} else {
|
||||||
|
networkstatus_free(networkstatus);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
free_cached_dir(d);
|
free_cached_dir(d);
|
||||||
digestmap_remove(cached_v2_networkstatus, identity);
|
digestmap_remove(cached_v2_networkstatus, identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router_get_trusted_dir_servers(&trusted_dirs);
|
||||||
|
if (digestmap_size(cached_v2_networkstatus) >
|
||||||
|
smartlist_len(trusted_dirs) + MAX_UNTRUSTED_NETWORKSTATUSES) {
|
||||||
|
/* We need to remove the oldest untrusted networkstatus. */
|
||||||
|
const char *oldest = NULL;
|
||||||
|
time_t oldest_published = TIME_MAX;
|
||||||
|
digestmap_iter_t *iter;
|
||||||
|
|
||||||
|
for (iter = digestmap_iter_init(cached_v2_networkstatus);
|
||||||
|
!digestmap_iter_done(iter);
|
||||||
|
iter = digestmap_iter_next(cached_v2_networkstatus, iter)) {
|
||||||
|
const char *ident;
|
||||||
|
void *val;
|
||||||
|
digestmap_iter_get(iter, &ident, &val);
|
||||||
|
d = val;
|
||||||
|
if (d->published < oldest_published &&
|
||||||
|
!router_get_trusteddirserver_by_digest(ident)) {
|
||||||
|
oldest = ident;
|
||||||
|
oldest_published = d->published;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tor_assert(oldest);
|
||||||
|
d = digestmap_remove(cached_v2_networkstatus, oldest);
|
||||||
|
if (d)
|
||||||
|
free_cached_dir(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper: If we're an authority for the right directory version (the
|
/** Helper: If we're an authority for the right directory version (the
|
||||||
|
@ -1938,6 +1938,30 @@ _compare_networkstatus_published_on(const void **_a, const void **_b)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add the parsed neworkstatus in <b>ns</b> (with original document in
|
||||||
|
* <b>s</b> to the disk cache (and the in-memory directory server cache) as
|
||||||
|
* appropriate. */
|
||||||
|
static int
|
||||||
|
add_networkstatus_to_cache(const char *s,
|
||||||
|
networkstatus_source_t source,
|
||||||
|
networkstatus_t *ns)
|
||||||
|
{
|
||||||
|
if (source != NS_FROM_CACHE) {
|
||||||
|
char *fn = networkstatus_get_cache_filename(ns);
|
||||||
|
if (write_str_to_file(fn, s, 0)<0) {
|
||||||
|
notice(LD_FS, "Couldn't write cached network status to \"%s\"", fn);
|
||||||
|
}
|
||||||
|
tor_free(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_options()->DirPort)
|
||||||
|
dirserv_set_cached_networkstatus_v2(s,
|
||||||
|
ns->identity_digest,
|
||||||
|
ns->published_on);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** How far in the future do we allow a network-status to get before removing
|
/** How far in the future do we allow a network-status to get before removing
|
||||||
* it? (seconds) */
|
* it? (seconds) */
|
||||||
#define NETWORKSTATUS_ALLOW_SKEW (48*60*60)
|
#define NETWORKSTATUS_ALLOW_SKEW (48*60*60)
|
||||||
@ -1969,7 +1993,8 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|||||||
int i, found;
|
int i, found;
|
||||||
time_t now;
|
time_t now;
|
||||||
int skewed = 0;
|
int skewed = 0;
|
||||||
trusted_dir_server_t *trusted_dir;
|
trusted_dir_server_t *trusted_dir = NULL;
|
||||||
|
const char *source_desc = NULL;
|
||||||
char fp[HEX_DIGEST_LEN+1];
|
char fp[HEX_DIGEST_LEN+1];
|
||||||
char published[ISO_TIME_LEN+1];
|
char published[ISO_TIME_LEN+1];
|
||||||
|
|
||||||
@ -1978,12 +2003,18 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|||||||
warn(LD_DIR, "Couldn't parse network status.");
|
warn(LD_DIR, "Couldn't parse network status.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
|
||||||
if (!(trusted_dir =
|
if (!(trusted_dir =
|
||||||
router_get_trusteddirserver_by_digest(ns->identity_digest))) {
|
router_get_trusteddirserver_by_digest(ns->identity_digest))) {
|
||||||
info(LD_DIR, "Network status was signed, but not by an authoritative "
|
info(LD_DIR, "Network status was signed, but not by an authoritative "
|
||||||
"directory we recognize.");
|
"directory we recognize.");
|
||||||
networkstatus_free(ns);
|
if (!get_options()->DirPort) {
|
||||||
return -1;
|
networkstatus_free(ns);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
source_desc = fp;
|
||||||
|
} else {
|
||||||
|
source_desc = trusted_dir->description;
|
||||||
}
|
}
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
if (arrived_at > now)
|
if (arrived_at > now)
|
||||||
@ -1996,7 +2027,7 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|||||||
if (ns->published_on > now + NETWORKSTATUS_ALLOW_SKEW) {
|
if (ns->published_on > now + NETWORKSTATUS_ALLOW_SKEW) {
|
||||||
warn(LD_GENERAL, "Network status from %s was published in the future "
|
warn(LD_GENERAL, "Network status from %s was published in the future "
|
||||||
"(%s GMT). Somebody is skewed here: check your clock. Not caching.",
|
"(%s GMT). Somebody is skewed here: check your clock. Not caching.",
|
||||||
trusted_dir->description, published);
|
source_desc, published);
|
||||||
skewed = 1;
|
skewed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2009,8 +2040,6 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
|
|
||||||
|
|
||||||
if (requested_fingerprints) {
|
if (requested_fingerprints) {
|
||||||
if (smartlist_string_isin(requested_fingerprints, fp)) {
|
if (smartlist_string_isin(requested_fingerprints, fp)) {
|
||||||
smartlist_string_remove(requested_fingerprints, fp);
|
smartlist_string_remove(requested_fingerprints, fp);
|
||||||
@ -2025,7 +2054,15 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source != NS_FROM_CACHE)
|
if (!trusted_dir) {
|
||||||
|
if (!skewed && get_options()->DirPort) {
|
||||||
|
add_networkstatus_to_cache(s, source, ns);
|
||||||
|
networkstatus_free(ns);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source != NS_FROM_CACHE && trusted_dir)
|
||||||
trusted_dir->n_networkstatus_failures = 0;
|
trusted_dir->n_networkstatus_failures = 0;
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
@ -2075,8 +2112,8 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|||||||
|
|
||||||
SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
|
SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
|
||||||
{
|
{
|
||||||
if (!router_get_by_descriptor_digest(rs->descriptor_digest))
|
if (!router_get_by_descriptor_digest(rs->descriptor_digest))
|
||||||
rs->need_to_mirror = 1;
|
rs->need_to_mirror = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
info(LD_DIR, "Setting networkstatus %s %s (published %s)",
|
info(LD_DIR, "Setting networkstatus %s %s (published %s)",
|
||||||
@ -2087,21 +2124,11 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|||||||
|
|
||||||
smartlist_sort(networkstatus_list, _compare_networkstatus_published_on);
|
smartlist_sort(networkstatus_list, _compare_networkstatus_published_on);
|
||||||
|
|
||||||
if (source != NS_FROM_CACHE && !skewed) {
|
if (!skewed)
|
||||||
char *fn = networkstatus_get_cache_filename(ns);
|
add_networkstatus_to_cache(s, source, ns);
|
||||||
if (write_str_to_file(fn, s, 0)<0) {
|
|
||||||
notice(LD_FS, "Couldn't write cached network status to \"%s\"", fn);
|
|
||||||
}
|
|
||||||
tor_free(fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
networkstatus_list_update_recent(now);
|
networkstatus_list_update_recent(now);
|
||||||
|
|
||||||
if (get_options()->DirPort && !skewed)
|
|
||||||
dirserv_set_cached_networkstatus_v2(s,
|
|
||||||
ns->identity_digest,
|
|
||||||
ns->published_on);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user