Browse Source

Calculate total bandwidth weights using the guardfraction bandwidths.

Now use the function introduced in the previous commit, to calculate the
total bandwidth weights when making the consensus.
George Kadianakis 9 years ago
parent
commit
f7a8b19184
1 changed files with 85 additions and 14 deletions
  1. 85 14
      src/or/dirvote.c

+ 85 - 14
src/or/dirvote.c

@@ -16,6 +16,7 @@
 #include "router.h"
 #include "routerlist.h"
 #include "routerparse.h"
+#include "entrynodes.h" /* needed for guardfraction methods */
 
 /**
  * \file dirvote.c
@@ -1007,6 +1008,86 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G,
   return 1;
 }
 
+/** Update total bandwidth weights (G/M/E/D/T) with the bandwidth of
+ *  the router in <b>rs</b>. */
+static void
+update_total_bandwidth_weights(const routerstatus_t *rs,
+                               int is_exit, int is_guard,
+                               int64_t *G, int64_t *M, int64_t *E, int64_t *D,
+                               int64_t *T)
+{
+  int default_bandwidth = rs->bandwidth_kb;
+  int guardfraction_bandwidth = 0;
+
+  if (!rs->has_bandwidth) {
+    log_warn(LD_BUG, "Missing consensus bandwidth for router %s",
+             rs->nickname);
+    return;
+  }
+
+  /* If this routerstatus represents a guard that we have
+   * guardfraction information on, use it to calculate its actual
+   * bandwidth. From proposal236:
+   *
+   *    Similarly, when calculating the bandwidth-weights line as in
+   *    section 3.8.3 of dir-spec.txt, directory authorities should treat N
+   *    as if fraction F of its bandwidth has the guard flag and (1-F) does
+   *    not.  So when computing the totals G,M,E,D, each relay N with guard
+   *    visibility fraction F and bandwidth B should be added as follows:
+   *
+   *    G' = G + F*B, if N does not have the exit flag
+   *    M' = M + (1-F)*B, if N does not have the exit flag
+   *
+   *    or
+   *
+   *    D' = D + F*B, if N has the exit flag
+   *    E' = E + (1-F)*B, if N has the exit flag
+   *
+   * In this block of code, we prepare the bandwidth values by setting
+   * the default_bandwidth to F*B and guardfraction_bandwidth to (1-F)*B. */
+  if (rs->has_guardfraction) {
+    guardfraction_bandwidth_t guardfraction_bw;
+
+    tor_assert(is_guard);
+
+    guard_get_guardfraction_bandwidth(&guardfraction_bw,
+                                      rs->bandwidth_kb,
+                                      rs->guardfraction_percentage);
+
+    default_bandwidth = guardfraction_bw.guard_bw;
+    guardfraction_bandwidth = guardfraction_bw.non_guard_bw;
+  }
+
+  /* Now calculate the total bandwidth weights with or without
+     guardfraction. Depending on the flags of the relay, add its
+     bandwidth to the appropriate weight pool. If it's a guard and
+     guardfraction is enabled, add its bandwidth to both pools as
+     indicated by the previous comment. */
+  *T += default_bandwidth;
+  if (is_exit && is_guard) {
+
+    *D += default_bandwidth;
+    if (rs->has_guardfraction) {
+      *E += guardfraction_bandwidth;
+    }
+
+  } else if (is_exit) {
+
+    *E += default_bandwidth;
+
+  } else if (is_guard) {
+
+    *G += default_bandwidth;
+    if (rs->has_guardfraction) {
+      *M += guardfraction_bandwidth;
+    }
+
+  } else {
+
+    *M += default_bandwidth;
+  }
+}
+
 /** Given a list of vote networkstatus_t in <b>votes</b>, our public
  * authority <b>identity_key</b>, our private authority <b>signing_key</b>,
  * and the number of <b>total_authorities</b> that we believe exist in our
@@ -1582,21 +1663,11 @@ networkstatus_compute_consensus(smartlist_t *votes,
       /* Fix bug 2203: Do not count BadExit nodes as Exits for bw weights */
       is_exit = is_exit && !is_bad_exit;
 
+      /* Update total bandwidth weights with the bandwidths of this router. */
       {
-        if (rs_out.has_bandwidth) {
-          T += rs_out.bandwidth_kb;
-          if (is_exit && is_guard)
-            D += rs_out.bandwidth_kb;
-          else if (is_exit)
-            E += rs_out.bandwidth_kb;
-          else if (is_guard)
-            G += rs_out.bandwidth_kb;
-          else
-            M += rs_out.bandwidth_kb;
-        } else {
-          log_warn(LD_BUG, "Missing consensus bandwidth for router %s",
-              rs_out.nickname);
-        }
+        update_total_bandwidth_weights(&rs_out,
+                                       is_exit, is_guard,
+                                       &G, &M, &E, &D, &T);
       }
 
       /* Ok, we already picked a descriptor digest we want to list