浏览代码

r14612@catbus: nickm | 2007-08-16 15:23:35 -0400
Initial work on proposal 108: have rephist.c track the information we want to be tracking for OR stability.


svn:r11147

Nick Mathewson 17 年之前
父节点
当前提交
357b4645cf
共有 4 个文件被更改,包括 123 次插入27 次删除
  1. 5 3
      doc/TODO
  2. 5 0
      src/or/main.c
  3. 3 0
      src/or/or.h
  4. 110 24
      src/or/rephist.c

+ 5 - 3
doc/TODO

@@ -101,11 +101,13 @@ Things we'd like to do in 0.2.0.x:
       - Start caching consensus documents once authorities make them
       - Start downloading and using consensus documents once caches serve them
     . 104: Long and Short Router Descriptors
-      . Merge proposal
+      o Merge proposal
       - Drop bandwidth history from router-descriptors
     - 105: Version negotiation for the Tor protocol
-    - 108: Base "Stable" Flag on Mean Time Between Failures
-      - Track mtbf in rephist.c
+    . 108: Base "Stable" Flag on Mean Time Between Failures
+      o Track mtbf in rephist.c
+      - Do not delete old stability information if we're an authority.
+      - Make sure authorities call up/down functions as appropriate.
       - Record mtbf between invocations
       - Base stable on mtbf.
     - 113: Simplifying directory authority administration

+ 5 - 0
src/or/main.c

@@ -844,6 +844,7 @@ run_scheduled_events(time_t now)
   static time_t time_to_reset_descriptor_failures = 0;
   static time_t time_to_add_entropy = 0;
   static time_t time_to_write_hs_statistics = 0;
+  static time_t time_to_downrate_stability = 0;
   or_options_t *options = get_options();
   int i;
   int have_dir_info;
@@ -931,6 +932,10 @@ run_scheduled_events(time_t now)
     dirserv_test_reachability(0);
   }
 
+  /** 1d. DOCDOC */
+  if (time_to_downrate_stability < now)
+    time_to_downrate_stability = rep_hist_downrate_old_runs(now);
+
   /** 2. Periodically, we consider getting a new directory, getting a
    * new running-routers list, and/or force-uploading our descriptor
    * (if we've passed our internal checks). */

+ 3 - 0
src/or/or.h

@@ -3117,6 +3117,9 @@ void rep_hist_update_state(or_state_t *state);
 int rep_hist_load_state(or_state_t *state, char **err);
 void rep_history_clean(time_t before);
 
+time_t rep_hist_downrate_old_runs(time_t now);
+double rep_hist_get_stability(const char *id, time_t when);
+
 void rep_hist_note_used_port(uint16_t port, time_t now);
 smartlist_t *rep_hist_get_predicted_ports(time_t now);
 void rep_hist_note_used_resolve(time_t now);

+ 110 - 24
src/or/rephist.c

@@ -20,6 +20,10 @@ static void hs_usage_init(void);
 uint64_t rephist_total_alloc=0;
 uint32_t rephist_total_num=0;
 
+#define STABILITY_EPSILON   0.0001
+#define STABILITY_ALPHA     0.9
+#define STABILITY_INTERVAL  (12*60*60)
+
 /** History of an OR-\>OR link. */
 typedef struct link_history_t {
   /** When did we start tracking this list? */
@@ -52,11 +56,18 @@ typedef struct or_history_t {
   time_t up_since;
   /** If nonzero, we have been unable to connect since this time. */
   time_t down_since;
+  /** DOCDOC */
+  unsigned long weighted_run_length;
+  time_t start_of_run;
+  double total_run_weights;
   /** Map from hex OR2 identity digest to a link_history_t for the link
    * from this OR to OR2. */
   digestmap_t *link_history_map;
 } or_history_t;
 
+/** DOCDOC */
+static time_t stability_last_downrated = 0;
+
 /** Map from hex OR identity digest to or_history_t. */
 static digestmap_t *history_map = NULL;
 
@@ -151,6 +162,42 @@ rep_hist_init(void)
   hs_usage_init();
 }
 
+/** DOCDOC */
+static void
+mark_or_down(or_history_t *hist, time_t when, int failed)
+{
+  if (hist->start_of_run) {
+    /*XXXX020 treat failure specially. */
+    long run_length = when - hist->start_of_run;
+    hist->weighted_run_length += run_length;
+    hist->total_run_weights += 1.0;
+    hist->start_of_run = 0;
+  }
+  if (hist->up_since) {
+    hist->uptime += (when - hist->up_since);
+    hist->up_since = 0;
+  }
+  if (failed && !hist->down_since) {
+    hist->down_since = when;
+  }
+}
+
+/** DOCDOC */
+static void
+mark_or_up(or_history_t *hist, time_t when)
+{
+  if (!hist->start_of_run) {
+    hist->start_of_run = when;
+  }
+  if (hist->down_since) {
+    hist->downtime += (when - hist->down_since);
+    hist->down_since = 0;
+  }
+  if (!hist->up_since) {
+    hist->up_since = when;
+  }
+}
+
 /** Remember that an attempt to connect to the OR with identity digest
  * <b>id</b> failed at <b>when</b>.
  */
@@ -162,12 +209,7 @@ rep_hist_note_connect_failed(const char* id, time_t when)
   if (!hist)
     return;
   ++hist->n_conn_fail;
-  if (hist->up_since) {
-    hist->uptime += (when - hist->up_since);
-    hist->up_since = 0;
-  }
-  if (!hist->down_since)
-    hist->down_since = when;
+  mark_or_down(hist, when, 1);
   hist->changed = when;
 }
 
@@ -182,12 +224,7 @@ rep_hist_note_connect_succeeded(const char* id, time_t when)
   if (!hist)
     return;
   ++hist->n_conn_ok;
-  if (hist->down_since) {
-    hist->downtime += (when - hist->down_since);
-    hist->down_since = 0;
-  }
-  if (!hist->up_since)
-    hist->up_since = when;
+  mark_or_up(hist, when);
   hist->changed = when;
 }
 
@@ -201,11 +238,7 @@ rep_hist_note_disconnect(const char* id, time_t when)
   hist = get_or_history(id);
   if (!hist)
     return;
-  ++hist->n_conn_ok;
-  if (hist->up_since) {
-    hist->uptime += (when - hist->up_since);
-    hist->up_since = 0;
-  }
+  mark_or_down(hist, when, 0);
   hist->changed = when;
 }
 
@@ -217,7 +250,7 @@ rep_hist_note_connection_died(const char* id, time_t when)
 {
   or_history_t *hist;
   if (!id) {
-    /* If conn has no nickname, it didn't complete its handshake, or something
+    /* If conn has no identity, it didn't complete its handshake, or something
      * went wrong.  Ignore it.
      */
     return;
@@ -225,15 +258,68 @@ rep_hist_note_connection_died(const char* id, time_t when)
   hist = get_or_history(id);
   if (!hist)
     return;
-  if (hist->up_since) {
-    hist->uptime += (when - hist->up_since);
-    hist->up_since = 0;
-  }
-  if (!hist->down_since)
-    hist->down_since = when;
+  mark_or_down(hist, when, 1);
   hist->changed = when;
 }
 
+/**DOCDOC*/
+time_t
+rep_hist_downrate_old_runs(time_t now)
+{
+  digestmap_iter_t *orhist_it;
+  const char *digest1;
+  or_history_t *hist;
+  void *hist_p;
+  double alpha = 1.0;
+
+  if (!history_map)
+    history_map = digestmap_new();
+  if (!stability_last_downrated)
+    stability_last_downrated = now;
+  if (stability_last_downrated + STABILITY_INTERVAL > now)
+    return stability_last_downrated + STABILITY_INTERVAL;
+
+  while (stability_last_downrated + STABILITY_INTERVAL < now) {
+    stability_last_downrated += STABILITY_INTERVAL;
+    alpha *= STABILITY_ALPHA;
+  }
+
+  for (orhist_it = digestmap_iter_init(history_map);
+       !digestmap_iter_done(orhist_it);
+       orhist_it = digestmap_iter_next(history_map,orhist_it)) {
+    digestmap_iter_get(orhist_it, &digest1, &hist_p);
+    hist = hist_p;
+
+    hist->weighted_run_length =
+      (unsigned long)(hist->weighted_run_length * alpha);
+    hist->total_run_weights *= alpha;
+  }
+
+  return stability_last_downrated + STABILITY_INTERVAL;
+}
+
+/**DOCDOC*/
+double
+rep_hist_get_stability(const char *id, time_t when)
+{
+  or_history_t *hist = get_or_history(id);
+  unsigned long total;
+  double total_weights;
+  if (!hist)
+    return 0.0;
+
+  total = hist->weighted_run_length;
+  total_weights = hist->total_run_weights;
+  if (hist->start_of_run) {
+    total += (when-hist->start_of_run);
+    total_weights += 1.0;
+  }
+  if (total_weights < STABILITY_EPSILON)
+    return 0.0;
+
+  return total / total_weights;
+}
+
 /** Remember that we successfully extended from the OR with identity
  * digest <b>from_id</b> to the OR with identity digest
  * <b>to_name</b>.