mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Tweaks to prevent obsolete restarting tors from hammering the dirservers. (1) Cache a received directory as soon as the signature checks out. (2) Treat a cached directory as "recent" based on its mtime. (3) If we have a recent directory, we dont need to fetch a newer one for DirFetchPostPeriod. This needs review!
svn:r2618
This commit is contained in:
parent
36bbab2f2b
commit
11d330be5e
@ -585,7 +585,7 @@ connection_dir_client_reached_eof(connection_t *conn)
|
||||
} else {
|
||||
log_fn(LOG_INFO,"updated routers.");
|
||||
}
|
||||
directory_has_arrived(); /* do things we've been waiting to do */
|
||||
directory_has_arrived(time(NULL)); /* do things we've been waiting to do */
|
||||
}
|
||||
|
||||
if(conn->purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) {
|
||||
|
@ -750,7 +750,6 @@ size_t dirserv_get_directory(const char **directory, int compress)
|
||||
static int dirserv_regenerate_directory(void)
|
||||
{
|
||||
char *new_directory;
|
||||
char filename[512];
|
||||
|
||||
new_directory = tor_malloc(MAX_DIR_SIZE);
|
||||
if (dirserv_dump_directory_to_string(new_directory, MAX_DIR_SIZE,
|
||||
@ -783,12 +782,6 @@ static int dirserv_regenerate_directory(void)
|
||||
exit(0);
|
||||
}
|
||||
tor_free(new_directory);
|
||||
if(get_data_directory(&options)) {
|
||||
tor_snprintf(filename,sizeof(filename),"%s/cached-directory", get_data_directory(&options));
|
||||
if(write_str_to_file(filename,the_directory,0) < 0) {
|
||||
log_fn(LOG_WARN, "Couldn't write cached directory to disk. Ignoring.");
|
||||
}
|
||||
}
|
||||
the_directory_is_dirty = 0;
|
||||
|
||||
return 0;
|
||||
|
@ -31,6 +31,9 @@ static uint64_t stats_n_bytes_read = 0;
|
||||
static uint64_t stats_n_bytes_written = 0;
|
||||
/** How many seconds have we been running? */
|
||||
long stats_n_seconds_uptime = 0;
|
||||
/** When do we next download a directory? */
|
||||
static time_t time_to_fetch_directory = 0;
|
||||
|
||||
|
||||
/** Array of all open connections; each element corresponds to the element of
|
||||
* poll_array in the same position. The first nfds elements are valid. */
|
||||
@ -359,11 +362,16 @@ static void conn_close_if_marked(int i) {
|
||||
}
|
||||
|
||||
/** This function is called whenever we successfully pull down a directory */
|
||||
void directory_has_arrived(void) {
|
||||
void directory_has_arrived(time_t now) {
|
||||
|
||||
log_fn(LOG_INFO, "A directory has arrived.");
|
||||
|
||||
has_fetched_directory=1;
|
||||
/* Don't try to upload or download anything for DirFetchPostPeriod
|
||||
* seconds after the directory we had when we started.
|
||||
*/
|
||||
if (!time_to_fetch_directory)
|
||||
time_to_fetch_directory = now + options.DirFetchPostPeriod;
|
||||
|
||||
if(server_mode()) { /* connect to the appropriate routers */
|
||||
router_retry_connections();
|
||||
@ -496,7 +504,6 @@ int proxy_mode(void) {
|
||||
* second by prepare_for_poll.
|
||||
*/
|
||||
static void run_scheduled_events(time_t now) {
|
||||
static long time_to_fetch_directory = 0;
|
||||
static time_t last_uploaded_services = 0;
|
||||
static time_t last_rotated_certificate = 0;
|
||||
static time_t time_to_check_listeners = 0;
|
||||
|
@ -1249,7 +1249,7 @@ int connection_is_writing(connection_t *conn);
|
||||
void connection_stop_writing(connection_t *conn);
|
||||
void connection_start_writing(connection_t *conn);
|
||||
|
||||
void directory_has_arrived(void);
|
||||
void directory_has_arrived(time_t now);
|
||||
int authdir_mode(void);
|
||||
int clique_mode(void);
|
||||
int server_mode(void);
|
||||
@ -1454,6 +1454,7 @@ routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
|
||||
routerinfo_t *router_get_by_digest(const char *digest);
|
||||
int router_digest_is_trusted_dir(const char *digest);
|
||||
void router_get_routerlist(routerlist_t **prouterlist);
|
||||
time_t routerlist_get_published_time(void);
|
||||
void routerlist_free(routerlist_t *routerlist);
|
||||
void routerinfo_free(routerinfo_t *router);
|
||||
routerinfo_t *routerinfo_copy(const routerinfo_t *router);
|
||||
|
@ -48,19 +48,29 @@ extern int has_fetched_directory; /**< from main.c */
|
||||
int router_reload_router_list(void)
|
||||
{
|
||||
char filename[512];
|
||||
int is_recent;
|
||||
struct stat st;
|
||||
if (get_data_directory(&options)) {
|
||||
char *s;
|
||||
tor_snprintf(filename,sizeof(filename),"%s/cached-directory", get_data_directory(&options));
|
||||
if (stat(filename, &st)) {
|
||||
log_fn(LOG_WARN, "Unable to check status for '%s': %s", filename,
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
s = read_file_to_str(filename,0);
|
||||
if (s) {
|
||||
tor_strstrip(s,"\r"); /* XXXX This is a bug workaround for win32. */
|
||||
log_fn(LOG_INFO, "Loading cached directory from %s", filename);
|
||||
if (router_load_routerlist_from_directory(s, NULL, 0) < 0) {
|
||||
is_recent = st.st_mtime > time(NULL) - 60*15;
|
||||
if (router_load_routerlist_from_directory(s, NULL, is_recent) < 0) {
|
||||
log_fn(LOG_WARN, "Cached directory '%s' was unparseable; ignoring.", filename);
|
||||
}
|
||||
if(routerlist && routerlist->published_on > time(NULL) - OLD_MIN_ONION_KEY_LIFETIME/2) {
|
||||
if(routerlist &&
|
||||
((routerlist->published_on > time(NULL) - OLD_MIN_ONION_KEY_LIFETIME/2)
|
||||
|| is_recent)) {
|
||||
/* XXX use new onion key lifetime when 0.0.8 servers are obsolete */
|
||||
directory_has_arrived(); /* do things we've been waiting to do */
|
||||
directory_has_arrived(st.st_mtime); /* do things we've been waiting to do */
|
||||
}
|
||||
tor_free(s);
|
||||
}
|
||||
@ -633,6 +643,12 @@ void router_get_routerlist(routerlist_t **prouterlist) {
|
||||
*prouterlist = routerlist;
|
||||
}
|
||||
|
||||
/** Return the publication time on the current routerlist, or 0 if we have no
|
||||
* routerlist. */
|
||||
time_t routerlist_get_published_time(void) {
|
||||
return routerlist ? routerlist->published_on : 0;
|
||||
}
|
||||
|
||||
/** Free all storage held by <b>router</b>. */
|
||||
void routerinfo_free(routerinfo_t *router)
|
||||
{
|
||||
@ -851,10 +867,6 @@ int router_load_routerlist_from_directory(const char *s,
|
||||
if (options.AuthoritativeDir) {
|
||||
/* Learn about the descriptors in the directory. */
|
||||
dirserv_load_from_directory_string(s);
|
||||
} else {
|
||||
/* Remember the directory. */
|
||||
if(dir_is_recent)
|
||||
dirserv_set_cached_directory(s, routerlist->published_on);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -343,6 +343,10 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
smartlist_free(tokens);
|
||||
tokens = NULL;
|
||||
|
||||
/* Now that we know the signature is okay, cache the directory. */
|
||||
/* XXXX009 extract published time if possible. */
|
||||
dirserv_set_cached_directory(str, time(NULL));
|
||||
|
||||
/* Now that we know the signature is okay, check the version. */
|
||||
if (check_version)
|
||||
check_software_version_against_directory(str, options.IgnoreVersion);
|
||||
|
Loading…
Reference in New Issue
Block a user