[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Tweaks to prevent obsolete restarting tors from hammering t...



Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv8056/src/or

Modified Files:
	directory.c dirserv.c main.c or.h routerlist.c routerparse.c 
Log Message:
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!

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.156
retrieving revision 1.157
diff -u -d -r1.156 -r1.157
--- directory.c	27 Oct 2004 21:14:11 -0000	1.156
+++ directory.c	28 Oct 2004 18:37:52 -0000	1.157
@@ -585,7 +585,7 @@
     } 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) {

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dirserv.c,v
retrieving revision 1.106
retrieving revision 1.107
diff -u -d -r1.106 -r1.107
--- dirserv.c	27 Oct 2004 18:14:38 -0000	1.106
+++ dirserv.c	28 Oct 2004 18:37:52 -0000	1.107
@@ -750,7 +750,6 @@
 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 @@
     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;

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.342
retrieving revision 1.343
diff -u -d -r1.342 -r1.343
--- main.c	27 Oct 2004 21:14:11 -0000	1.342
+++ main.c	28 Oct 2004 18:37:52 -0000	1.343
@@ -31,6 +31,9 @@
 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 @@
 }
 
 /** 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 @@
  * 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;

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.447
retrieving revision 1.448
diff -u -d -r1.447 -r1.448
--- or.h	27 Oct 2004 21:14:11 -0000	1.447
+++ or.h	28 Oct 2004 18:37:52 -0000	1.448
@@ -1249,7 +1249,7 @@
 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_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);

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerlist.c,v
retrieving revision 1.170
retrieving revision 1.171
diff -u -d -r1.170 -r1.171
--- routerlist.c	27 Oct 2004 21:14:11 -0000	1.170
+++ routerlist.c	28 Oct 2004 18:37:52 -0000	1.171
@@ -48,19 +48,29 @@
 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 @@
   *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 @@
   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;
 }

Index: routerparse.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerparse.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -d -r1.67 -r1.68
--- routerparse.c	27 Oct 2004 21:14:11 -0000	1.67
+++ routerparse.c	28 Oct 2004 18:37:52 -0000	1.68
@@ -343,6 +343,10 @@
   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);