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:
Nick Mathewson 2004-10-28 18:37:52 +00:00
parent 36bbab2f2b
commit 11d330be5e
6 changed files with 35 additions and 18 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
} }

View File

@ -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);