Browse Source

Merge remote branch 'origin/maint-0.2.2'

Nick Mathewson 13 years ago
parent
commit
d52a99dc77
5 changed files with 42 additions and 2 deletions
  1. 8 0
      changes/hsdir_assignment
  2. 18 1
      src/or/dirserv.c
  3. 1 1
      src/or/dirvote.c
  4. 14 0
      src/or/rephist.c
  5. 1 0
      src/or/rephist.h

+ 8 - 0
changes/hsdir_assignment

@@ -0,0 +1,8 @@
+  o Security fixes:
+    - Directory authorities now use data collected from rephist when
+      choosing whether to assign the HSDir flag to relays, instead of
+      trusting the uptime value the relay reports in its descriptor.
+      This helps prevent an attack where a small set of nodes with
+      frequently-changing identity keys can blackhole a hidden service.
+      (Only authorities need upgrade; others will be fine once they do.)
+      Bugfix on 0.2.0.10-alpha; fixes bug 2709.

+ 18 - 1
src/or/dirserv.c

@@ -44,6 +44,8 @@
 
 extern time_t time_of_process_start; /* from main.c */
 
+extern long stats_n_seconds_working; /* from main.c */
+
 /** Do we need to regenerate the v1 directory when someone asks for it? */
 static time_t the_directory_is_dirty = 1;
 /** Do we need to regenerate the v1 runningrouters document when somebody
@@ -1803,7 +1805,22 @@ static int
 dirserv_thinks_router_is_hs_dir(const routerinfo_t *router,
                                 const node_t *node, time_t now)
 {
-  long uptime = real_uptime(router, now);
+
+  long uptime;
+
+  /* If we haven't been running for at least
+   * get_options()->MinUptimeHidServDirectoryV2 seconds, we can't
+   * have accurate data telling us a relay has been up for at least
+   * that long. We also want to allow a bit of slack: Reachability
+   * tests aren't instant. If we haven't been running long enough,
+   * trust the relay. */
+
+  if (stats_n_seconds_working >
+      get_options()->MinUptimeHidServDirectoryV2 * 1.1)
+    uptime = MIN(rep_hist_get_uptime(router->cache_info.identity_digest, now),
+                 real_uptime(router, now));
+  else
+    uptime = real_uptime(router, now);
 
   /* XXX We shouldn't need to check dir_port, but we do because of
    * bug 1693. In the future, once relays set wants_to_be_hs_dir

+ 1 - 1
src/or/dirvote.c

@@ -3073,7 +3073,7 @@ dirvote_compute_consensuses(void)
   n_votes = smartlist_len(pending_vote_list);
   if (n_votes <= n_voters/2) {
     log_warn(LD_DIR, "We don't have enough votes to generate a consensus: "
-             "%d of %d", n_votes, n_voters/2);
+             "%d of %d", n_votes, n_voters/2+1);
     goto err;
   }
   tor_assert(pending_vote_list);

+ 14 - 0
src/or/rephist.c

@@ -529,6 +529,20 @@ get_weighted_fractional_uptime(or_history_t *hist, time_t when)
   return ((double) up) / total;
 }
 
+/** Return how long the router whose identity digest is <b>id</b> has
+ *  been reachable. Return 0 if the router is unknown or currently deemed
+ *  unreachable. */
+long
+rep_hist_get_uptime(const char *id, time_t when)
+{
+  or_history_t *hist = get_or_history(id);
+  if (!hist)
+    return 0;
+  if (!hist->start_of_run || when < hist->start_of_run)
+    return 0;
+  return when - hist->start_of_run;
+}
+
 /** Return an estimated MTBF for the router whose identity digest is
  * <b>id</b>. Return 0 if the router is unknown. */
 double

+ 1 - 0
src/or/rephist.h

@@ -40,6 +40,7 @@ int rep_hist_record_mtbf_data(time_t now, int missing_means_down);
 int rep_hist_load_mtbf_data(time_t now);
 
 time_t rep_hist_downrate_old_runs(time_t now);
+long rep_hist_get_uptime(const char *id, time_t when);
 double rep_hist_get_stability(const char *id, time_t when);
 double rep_hist_get_weighted_fractional_uptime(const char *id, time_t when);
 long rep_hist_get_weighted_time_known(const char *id, time_t when);