Browse Source

Introduce torrc option NumPrimaryGuards

George Kadianakis 6 years ago
parent
commit
d00ed406e0
6 changed files with 47 additions and 6 deletions
  1. 3 0
      changes/bug25843
  2. 7 0
      doc/tor.1.txt
  3. 6 0
      src/or/config.c
  4. 10 6
      src/or/entrynodes.c
  5. 2 0
      src/or/or.h
  6. 19 0
      src/test/test_entrynodes.c

+ 3 - 0
changes/bug25843

@@ -0,0 +1,3 @@
+  o Minor feature (entry guards):
+    - Introduce torrc option NumPrimaryGuards for controlling the number of
+      primary guards. Closes ticket 25843.

+ 7 - 0
doc/tor.1.txt

@@ -1344,6 +1344,13 @@ The following options are useful only for clients (that is, if
     number from the guard-n-primary-guards-to-use consensus parameter, and
     default to 1 if the consensus parameter isn't set. (Default: 0)
 
+[[NumPrimaryGuards]] **NumPrimaryGuards** __NUM__::
+    If UseEntryGuards is set to 1, we will try to pick NUM routers for our
+    primary guard list, which is the set of routers we strongly prefer when
+    connecting to the Tor network. If NUM is 0, we try to learn the number from
+    the guard-n-primary-guards consensus parameter, and default to 3 if the
+    consensus parameter isn't set. (Default: 0)
+
 [[NumDirectoryGuards]] **NumDirectoryGuards** __NUM__::
     If UseEntryGuards is set to 1, we try to make sure we have at least NUM
     routers to use as directory guards. If this option is set to 0, use the

+ 6 - 0
src/or/config.c

@@ -457,6 +457,7 @@ static config_var_t option_vars_[] = {
   V(NumCPUs,                     UINT,     "0"),
   V(NumDirectoryGuards,          UINT,     "0"),
   V(NumEntryGuards,              UINT,     "0"),
+  V(NumPrimaryGuards,            UINT,     "0"),
   V(OfflineMasterKey,            BOOL,     "0"),
   OBSOLETE("ORListenAddress"),
   VPORT(ORPort),
@@ -3763,6 +3764,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
              "http://freehaven.net/anonbib/#hs-attack06 for details.");
   }
 
+  if (options->NumPrimaryGuards && options->NumEntryGuards &&
+      options->NumEntryGuards > options->NumPrimaryGuards) {
+    REJECT("NumEntryGuards must not be greater than NumPrimaryGuards.");
+  }
+
   if (options->EntryNodes &&
       routerset_is_list(options->EntryNodes) &&
       (routerset_len(options->EntryNodes) == 1) &&

+ 10 - 6
src/or/entrynodes.c

@@ -432,14 +432,15 @@ get_guard_confirmed_min_lifetime(void)
 STATIC int
 get_n_primary_guards(void)
 {
-  const int n = get_options()->NumEntryGuards;
-  const int n_dir = get_options()->NumDirectoryGuards;
-  if (n > 5) {
-    return MAX(n_dir, n + n / 2);
-  } else if (n >= 1) {
-    return MAX(n_dir, n * 2);
+  /* If the user has explicitly configured the number of primary guards, do
+   * what the user wishes to do */
+  const int configured_primaries = get_options()->NumPrimaryGuards;
+  if (configured_primaries) {
+    return configured_primaries;
   }
 
+  /* otherwise check for consensus parameter and if that's not set either, just
+   * use the default value. */
   return networkstatus_get_param(NULL,
                                  "guard-n-primary-guards",
                                  DFLT_N_PRIMARY_GUARDS, 1, INT32_MAX);
@@ -454,6 +455,9 @@ get_n_primary_guards_to_use(guard_usage_t usage)
   int configured;
   const char *param_name;
   int param_default;
+
+  /* If the user has explicitly configured the amount of guards, use
+     that. Otherwise, fall back to the default value. */
   if (usage == GUARD_USAGE_DIRGUARD) {
     configured = get_options()->NumDirectoryGuards;
     param_name = "guard-n-primary-dir-guards-to-use";

+ 2 - 0
src/or/or.h

@@ -4148,6 +4148,8 @@ typedef struct {
 
   int NumDirectoryGuards; /**< How many dir guards do we try to establish?
                            * If 0, use value from NumEntryGuards. */
+  int NumPrimaryGuards; /**< How many primary guards do we want? */
+
   int RephistTrackTime; /**< How many seconds do we keep rephist info? */
   /** Should we always fetch our dir info on the mirror schedule (which
    * means directly from the authorities) no matter our other config? */

+ 19 - 0
src/test/test_entrynodes.c

@@ -2679,6 +2679,23 @@ test_enty_guard_should_expire_waiting(void *arg)
   tor_free(fake_state);
 }
 
+/** Test that the number of primary guards can be controlled using torrc */
+static void
+test_entry_guard_number_of_primaries(void *arg)
+{
+  (void) arg;
+
+  /* Get default value */
+  tt_int_op(get_n_primary_guards(), OP_EQ, DFLT_N_PRIMARY_GUARDS);
+
+  /* Set number of primaries using torrc */
+  get_options_mutable()->NumPrimaryGuards = 42;
+  tt_int_op(get_n_primary_guards(), OP_EQ, 42);
+
+ done:
+  ;
+}
+
 static void
 mock_directory_initiate_request(directory_request_t *req)
 {
@@ -2826,6 +2843,8 @@ struct testcase_t entrynodes_tests[] = {
     test_entry_guard_parse_from_state_broken, TT_FORK, NULL, NULL },
   { "get_guard_selection_by_name",
     test_entry_guard_get_guard_selection_by_name, TT_FORK, NULL, NULL },
+  { "number_of_primaries",
+    test_entry_guard_number_of_primaries, TT_FORK, NULL, NULL },
   BFN_TEST(choose_selection_initial),
   BFN_TEST(add_single_guard),
   BFN_TEST(node_filter),