Parcourir la source

Introduce torrc option NumPrimaryGuards

George Kadianakis il y a 6 ans
Parent
commit
d00ed406e0
6 fichiers modifiés avec 47 ajouts et 6 suppressions
  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
     number from the guard-n-primary-guards-to-use consensus parameter, and
     default to 1 if the consensus parameter isn't set. (Default: 0)
     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__::
 [[NumDirectoryGuards]] **NumDirectoryGuards** __NUM__::
     If UseEntryGuards is set to 1, we try to make sure we have at least 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
     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(NumCPUs,                     UINT,     "0"),
   V(NumDirectoryGuards,          UINT,     "0"),
   V(NumDirectoryGuards,          UINT,     "0"),
   V(NumEntryGuards,              UINT,     "0"),
   V(NumEntryGuards,              UINT,     "0"),
+  V(NumPrimaryGuards,            UINT,     "0"),
   V(OfflineMasterKey,            BOOL,     "0"),
   V(OfflineMasterKey,            BOOL,     "0"),
   OBSOLETE("ORListenAddress"),
   OBSOLETE("ORListenAddress"),
   VPORT(ORPort),
   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.");
              "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 &&
   if (options->EntryNodes &&
       routerset_is_list(options->EntryNodes) &&
       routerset_is_list(options->EntryNodes) &&
       (routerset_len(options->EntryNodes) == 1) &&
       (routerset_len(options->EntryNodes) == 1) &&

+ 10 - 6
src/or/entrynodes.c

@@ -432,14 +432,15 @@ get_guard_confirmed_min_lifetime(void)
 STATIC int
 STATIC int
 get_n_primary_guards(void)
 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,
   return networkstatus_get_param(NULL,
                                  "guard-n-primary-guards",
                                  "guard-n-primary-guards",
                                  DFLT_N_PRIMARY_GUARDS, 1, INT32_MAX);
                                  DFLT_N_PRIMARY_GUARDS, 1, INT32_MAX);
@@ -454,6 +455,9 @@ get_n_primary_guards_to_use(guard_usage_t usage)
   int configured;
   int configured;
   const char *param_name;
   const char *param_name;
   int param_default;
   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) {
   if (usage == GUARD_USAGE_DIRGUARD) {
     configured = get_options()->NumDirectoryGuards;
     configured = get_options()->NumDirectoryGuards;
     param_name = "guard-n-primary-dir-guards-to-use";
     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?
   int NumDirectoryGuards; /**< How many dir guards do we try to establish?
                            * If 0, use value from NumEntryGuards. */
                            * 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? */
   int RephistTrackTime; /**< How many seconds do we keep rephist info? */
   /** Should we always fetch our dir info on the mirror schedule (which
   /** Should we always fetch our dir info on the mirror schedule (which
    * means directly from the authorities) no matter our other config? */
    * 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);
   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
 static void
 mock_directory_initiate_request(directory_request_t *req)
 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 },
     test_entry_guard_parse_from_state_broken, TT_FORK, NULL, NULL },
   { "get_guard_selection_by_name",
   { "get_guard_selection_by_name",
     test_entry_guard_get_guard_selection_by_name, TT_FORK, NULL, NULL },
     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(choose_selection_initial),
   BFN_TEST(add_single_guard),
   BFN_TEST(add_single_guard),
   BFN_TEST(node_filter),
   BFN_TEST(node_filter),