Browse Source

Write GuardFraction information to consensus.

If we've seen enough votes with guardfraction information, write down
the GuardFraction string in the consensus.
George Kadianakis 10 years ago
parent
commit
db805b9170
2 changed files with 39 additions and 4 deletions
  1. 34 3
      src/or/dirvote.c
  2. 5 1
      src/or/dirvote.h

+ 34 - 3
src/or/dirvote.c

@@ -1266,8 +1266,11 @@ networkstatus_compute_consensus(smartlist_t *votes,
                                          sizeof(uint32_t));
                                          sizeof(uint32_t));
     uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
     uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
                                            sizeof(uint32_t));
                                            sizeof(uint32_t));
+    uint32_t *measured_guardfraction = tor_calloc(smartlist_len(votes),
+                                                  sizeof(uint32_t));
     int num_bandwidths;
     int num_bandwidths;
     int num_mbws;
     int num_mbws;
+    int num_guardfraction_inputs;
 
 
     int *n_voter_flags; /* n_voter_flags[j] is the number of flags that
     int *n_voter_flags; /* n_voter_flags[j] is the number of flags that
                          * votes[j] knows about. */
                          * votes[j] knows about. */
@@ -1376,7 +1379,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
 
 
     /* We need to know how many votes measure bandwidth. */
     /* We need to know how many votes measure bandwidth. */
     n_authorities_measuring_bandwidth = 0;
     n_authorities_measuring_bandwidth = 0;
-    SMARTLIST_FOREACH(votes, networkstatus_t *, v,
+    SMARTLIST_FOREACH(votes, const networkstatus_t *, v,
        if (v->has_measured_bws) {
        if (v->has_measured_bws) {
          ++n_authorities_measuring_bandwidth;
          ++n_authorities_measuring_bandwidth;
        }
        }
@@ -1418,6 +1421,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
       smartlist_clear(versions);
       smartlist_clear(versions);
       num_bandwidths = 0;
       num_bandwidths = 0;
       num_mbws = 0;
       num_mbws = 0;
+      num_guardfraction_inputs = 0;
 
 
       /* Okay, go through all the entries for this digest. */
       /* Okay, go through all the entries for this digest. */
       SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
       SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
@@ -1451,6 +1455,12 @@ networkstatus_compute_consensus(smartlist_t *votes,
           chosen_name = rs->status.nickname;
           chosen_name = rs->status.nickname;
         }
         }
 
 
+        /* Count guardfraction votes and note down the values. */
+        if (rs->status.has_guardfraction) {
+          measured_guardfraction[num_guardfraction_inputs++] =
+            rs->status.guardfraction_percentage;
+        }
+
         /* count bandwidths */
         /* count bandwidths */
         if (rs->has_measured_bw)
         if (rs->has_measured_bw)
           measured_bws_kb[num_mbws++] = rs->measured_bw_kb;
           measured_bws_kb[num_mbws++] = rs->measured_bw_kb;
@@ -1540,6 +1550,17 @@ networkstatus_compute_consensus(smartlist_t *votes,
         chosen_version = NULL;
         chosen_version = NULL;
       }
       }
 
 
+      /* If it's a guard and we have enough guardfraction votes,
+         calculate its consensus guardfraction value. */
+      if (is_guard && num_guardfraction_inputs > 2 &&
+          consensus_method >= MIN_METHOD_FOR_GUARDFRACTION) {
+        rs_out.has_guardfraction = 1;
+        rs_out.guardfraction_percentage = median_uint32(measured_guardfraction,
+                                                     num_guardfraction_inputs);
+        /* final value should be an integer percentage! */
+        tor_assert(rs_out.guardfraction_percentage <= 100);
+      }
+
       /* Pick a bandwidth */
       /* Pick a bandwidth */
       if (num_mbws > 2) {
       if (num_mbws > 2) {
         rs_out.has_bandwidth = 1;
         rs_out.has_bandwidth = 1;
@@ -1694,11 +1715,21 @@ networkstatus_compute_consensus(smartlist_t *votes,
       smartlist_add(chunks, tor_strdup("\n"));
       smartlist_add(chunks, tor_strdup("\n"));
       /*     Now the weight line. */
       /*     Now the weight line. */
       if (rs_out.has_bandwidth) {
       if (rs_out.has_bandwidth) {
+        char *guardfraction_str = NULL;
         int unmeasured = rs_out.bw_is_unmeasured &&
         int unmeasured = rs_out.bw_is_unmeasured &&
           consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW;
           consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW;
-        smartlist_add_asprintf(chunks, "w Bandwidth=%d%s\n",
+
+        /* If we have guardfraction info, include it in the 'w' line. */
+        if (rs_out.has_guardfraction) {
+          tor_asprintf(&guardfraction_str,
+                       " GuardFraction=%u", rs_out.guardfraction_percentage);
+        }
+        smartlist_add_asprintf(chunks, "w Bandwidth=%d%s%s\n",
                                rs_out.bandwidth_kb,
                                rs_out.bandwidth_kb,
-                               unmeasured?" Unmeasured=1":"");
+                               unmeasured?" Unmeasured=1":"",
+                               guardfraction_str ? guardfraction_str : "");
+
+        tor_free(guardfraction_str);
       }
       }
 
 
       /*     Now the exitpolicy summary line. */
       /*     Now the exitpolicy summary line. */

+ 5 - 1
src/or/dirvote.h

@@ -55,7 +55,7 @@
 #define MIN_SUPPORTED_CONSENSUS_METHOD 13
 #define MIN_SUPPORTED_CONSENSUS_METHOD 13
 
 
 /** The highest consensus method that we currently support. */
 /** The highest consensus method that we currently support. */
-#define MAX_SUPPORTED_CONSENSUS_METHOD 18
+#define MAX_SUPPORTED_CONSENSUS_METHOD 19
 
 
 /** Lowest consensus method where microdesc consensuses omit any entry
 /** Lowest consensus method where microdesc consensuses omit any entry
  * with no microdesc. */
  * with no microdesc. */
@@ -79,6 +79,10 @@
  * microdescriptors. */
  * microdescriptors. */
 #define MIN_METHOD_FOR_ID_HASH_IN_MD 18
 #define MIN_METHOD_FOR_ID_HASH_IN_MD 18
 
 
+/** Lowest consensus method where authorities may include
+ * GuardFraction information in microdescriptors. */
+#define MIN_METHOD_FOR_GUARDFRACTION 19
+
 /** Default bandwidth to clip unmeasured bandwidths to using method >=
 /** Default bandwidth to clip unmeasured bandwidths to using method >=
  * MIN_METHOD_TO_CLIP_UNMEASURED_BW */
  * MIN_METHOD_TO_CLIP_UNMEASURED_BW */
 #define DEFAULT_MAX_UNMEASURED_BW_KB 20
 #define DEFAULT_MAX_UNMEASURED_BW_KB 20