[tor-commits] [tor/master] Upload descriptors more often when recent desc is unlisted

nickm at torproject.org nickm at torproject.org
Wed Sep 7 19:03:57 UTC 2011


commit 1f4b6944c06fce5befc3b8a21d252ba946632f63
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Jun 22 12:27:27 2011 -0400

    Upload descriptors more often when recent desc is unlisted
    
    Right now we only force a new descriptor upload every 18 hours.
    This can make servers become unlisted if they upload a descriptor at
    time T which the authorities reject as being "too similar" to one
    they uploaded before. Nothing will actually make the server upload a
    new descriptor later on, until another 18 hours have passed.
    
    This patch changes the upload behavior so that the 18 hour interval
    applies only when we're listed in a live consensus with a descriptor
    published within the last 18 hours.  Otherwise--if we're not listed
    in the live consensus, or if we're listed with a publication time
    over 18 hours in the past--we upload a new descriptor every 90
    minutes.
    
    This is an attempted bugfix for #3327.  If we merge it, it should
    obsolete #535.
---
 changes/bug3327 |    8 ++++++++
 src/or/main.c   |    6 +-----
 src/or/router.c |   44 +++++++++++++++++++++++++++++++++++++++++---
 src/or/router.h |    2 +-
 4 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/changes/bug3327 b/changes/bug3327
new file mode 100644
index 0000000..32a8b9c
--- /dev/null
+++ b/changes/bug3327
@@ -0,0 +1,8 @@
+  o Major features:
+    - Relays now try regenerating and uploading their descriptor more
+      frequently if they are not listed in the consensus, or if the
+      version of their descriptor listed in the consensus is too
+      old. This fix should prevent situations where a server declines
+      to re-publish itself because it has done so too recently, even
+      though the authorities decided not to list its recent-enough
+      descriptor. Fix for bug 3327.
diff --git a/src/or/main.c b/src/or/main.c
index 2cdbe71..af769c4 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1326,11 +1326,7 @@ run_scheduled_events(time_t now)
       time_to_check_ipaddress = now + CHECK_IPADDRESS_INTERVAL;
       check_descriptor_ipaddress_changed(now);
     }
-/** If our router descriptor ever goes this long without being regenerated
- * because something changed, we force an immediate regenerate-and-upload. */
-#define FORCE_REGENERATE_DESCRIPTOR_INTERVAL (18*60*60)
-    mark_my_descriptor_dirty_if_older_than(
-                                  now - FORCE_REGENERATE_DESCRIPTOR_INTERVAL);
+    mark_my_descriptor_dirty_if_too_old(now);
     consider_publishable_server(0);
     /* also, check religiously for reachability, if it's within the first
      * 20 minutes of our uptime. */
diff --git a/src/or/router.c b/src/or/router.c
index 531d3fb..ccaa139 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1610,12 +1610,50 @@ router_rebuild_descriptor(int force)
   return 0;
 }
 
-/** Mark descriptor out of date if it's older than <b>when</b> */
+/** If our router descriptor ever goes this long without being regenerated
+ * because something changed, we force an immediate regenerate-and-upload. */
+#define FORCE_REGENERATE_DESCRIPTOR_INTERVAL (18*60*60)
+
+/** If our router descriptor seems to be missing or unacceptable according
+ * to the authorities, regenerate and reupload it _this_ often. */
+#define FAST_RETRY_DESCRIPTOR_INTERVAL (90*60)
+
+/** Mark descriptor out of date if it's been "too long" since we last tried
+ * to upload one. */
 void
-mark_my_descriptor_dirty_if_older_than(time_t when)
+mark_my_descriptor_dirty_if_too_old(time_t now)
 {
-  if (desc_clean_since < when)
+  networkstatus_t *ns;
+  routerstatus_t *rs;
+  const char *retry_fast_reason = NULL; /* Set if we should retry frequently */
+  const time_t slow_cutoff = now - FORCE_REGENERATE_DESCRIPTOR_INTERVAL;
+  const time_t fast_cutoff = now - FAST_RETRY_DESCRIPTOR_INTERVAL;
+
+  /* If it's already dirty, don't mark it. */
+  if (! desc_clean_since)
+    return;
+
+  /* If it's older than FORCE_REGENERATE_DESCRIPTOR_INTERVAL, it's always
+   * time to rebuild it. */
+  if (desc_clean_since < slow_cutoff) {
     mark_my_descriptor_dirty("time for new descriptor");
+    return;
+  }
+  /* Now we see whether we want to be retrying frequently or no.  The
+   * rule here is that we'll retry frequently if we aren't listed in the
+   * live consensus we have, or if the publication time of the
+   * descriptor listed for us in the consensus is very old. */
+  ns = networkstatus_get_live_consensus(now);
+  if (ns) {
+    rs = networkstatus_vote_find_entry(ns, server_identitykey_digest);
+    if (rs == NULL)
+      retry_fast_reason = "not listed in consensus";
+    else if (rs->published_on < slow_cutoff)
+      retry_fast_reason = "version listed in consensus is quite old";
+  }
+
+  if (retry_fast_reason && desc_clean_since < fast_cutoff)
+    mark_my_descriptor_dirty(retry_fast_reason);
 }
 
 /** Call when the current descriptor is out of date. */
diff --git a/src/or/router.h b/src/or/router.h
index f6d3c12..af202e6 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -62,7 +62,7 @@ void consider_publishable_server(int force);
 int should_refuse_unknown_exits(const or_options_t *options);
 
 void router_upload_dir_desc_to_dirservers(int force);
-void mark_my_descriptor_dirty_if_older_than(time_t when);
+void mark_my_descriptor_dirty_if_too_old(time_t now);
 void mark_my_descriptor_dirty(const char *reason);
 void check_descriptor_bandwidth_changed(time_t now);
 void check_descriptor_ipaddress_changed(time_t now);





More information about the tor-commits mailing list