mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +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 {
|
} else {
|
||||||
log_fn(LOG_INFO,"updated routers.");
|
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) {
|
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)
|
static int dirserv_regenerate_directory(void)
|
||||||
{
|
{
|
||||||
char *new_directory;
|
char *new_directory;
|
||||||
char filename[512];
|
|
||||||
|
|
||||||
new_directory = tor_malloc(MAX_DIR_SIZE);
|
new_directory = tor_malloc(MAX_DIR_SIZE);
|
||||||
if (dirserv_dump_directory_to_string(new_directory, 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);
|
exit(0);
|
||||||
}
|
}
|
||||||
tor_free(new_directory);
|
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;
|
the_directory_is_dirty = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -31,6 +31,9 @@ static uint64_t stats_n_bytes_read = 0;
|
|||||||
static uint64_t stats_n_bytes_written = 0;
|
static uint64_t stats_n_bytes_written = 0;
|
||||||
/** How many seconds have we been running? */
|
/** How many seconds have we been running? */
|
||||||
long stats_n_seconds_uptime = 0;
|
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
|
/** Array of all open connections; each element corresponds to the element of
|
||||||
* poll_array in the same position. The first nfds elements are valid. */
|
* 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 */
|
/** 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.");
|
log_fn(LOG_INFO, "A directory has arrived.");
|
||||||
|
|
||||||
has_fetched_directory=1;
|
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 */
|
if(server_mode()) { /* connect to the appropriate routers */
|
||||||
router_retry_connections();
|
router_retry_connections();
|
||||||
@ -496,7 +504,6 @@ int proxy_mode(void) {
|
|||||||
* second by prepare_for_poll.
|
* second by prepare_for_poll.
|
||||||
*/
|
*/
|
||||||
static void run_scheduled_events(time_t now) {
|
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_uploaded_services = 0;
|
||||||
static time_t last_rotated_certificate = 0;
|
static time_t last_rotated_certificate = 0;
|
||||||
static time_t time_to_check_listeners = 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_stop_writing(connection_t *conn);
|
||||||
void connection_start_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 authdir_mode(void);
|
||||||
int clique_mode(void);
|
int clique_mode(void);
|
||||||
int server_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);
|
routerinfo_t *router_get_by_digest(const char *digest);
|
||||||
int router_digest_is_trusted_dir(const char *digest);
|
int router_digest_is_trusted_dir(const char *digest);
|
||||||
void router_get_routerlist(routerlist_t **prouterlist);
|
void router_get_routerlist(routerlist_t **prouterlist);
|
||||||
|
time_t routerlist_get_published_time(void);
|
||||||
void routerlist_free(routerlist_t *routerlist);
|
void routerlist_free(routerlist_t *routerlist);
|
||||||
void routerinfo_free(routerinfo_t *router);
|
void routerinfo_free(routerinfo_t *router);
|
||||||
routerinfo_t *routerinfo_copy(const 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)
|
int router_reload_router_list(void)
|
||||||
{
|
{
|
||||||
char filename[512];
|
char filename[512];
|
||||||
|
int is_recent;
|
||||||
|
struct stat st;
|
||||||
if (get_data_directory(&options)) {
|
if (get_data_directory(&options)) {
|
||||||
char *s;
|
char *s;
|
||||||
tor_snprintf(filename,sizeof(filename),"%s/cached-directory", get_data_directory(&options));
|
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);
|
s = read_file_to_str(filename,0);
|
||||||
if (s) {
|
if (s) {
|
||||||
tor_strstrip(s,"\r"); /* XXXX This is a bug workaround for win32. */
|
tor_strstrip(s,"\r"); /* XXXX This is a bug workaround for win32. */
|
||||||
log_fn(LOG_INFO, "Loading cached directory from %s", filename);
|
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);
|
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 */
|
/* 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);
|
tor_free(s);
|
||||||
}
|
}
|
||||||
@ -633,6 +643,12 @@ void router_get_routerlist(routerlist_t **prouterlist) {
|
|||||||
*prouterlist = routerlist;
|
*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>. */
|
/** Free all storage held by <b>router</b>. */
|
||||||
void routerinfo_free(routerinfo_t *router)
|
void routerinfo_free(routerinfo_t *router)
|
||||||
{
|
{
|
||||||
@ -851,10 +867,6 @@ int router_load_routerlist_from_directory(const char *s,
|
|||||||
if (options.AuthoritativeDir) {
|
if (options.AuthoritativeDir) {
|
||||||
/* Learn about the descriptors in the directory. */
|
/* Learn about the descriptors in the directory. */
|
||||||
dirserv_load_from_directory_string(s);
|
dirserv_load_from_directory_string(s);
|
||||||
} else {
|
|
||||||
/* Remember the directory. */
|
|
||||||
if(dir_is_recent)
|
|
||||||
dirserv_set_cached_directory(s, routerlist->published_on);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -343,6 +343,10 @@ router_parse_routerlist_from_directory(const char *str,
|
|||||||
smartlist_free(tokens);
|
smartlist_free(tokens);
|
||||||
tokens = NULL;
|
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. */
|
/* Now that we know the signature is okay, check the version. */
|
||||||
if (check_version)
|
if (check_version)
|
||||||
check_software_version_against_directory(str, options.IgnoreVersion);
|
check_software_version_against_directory(str, options.IgnoreVersion);
|
||||||
|
Loading…
Reference in New Issue
Block a user