|
@@ -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
|