[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [proposal 136] Re: Proposal: Simplify Configuration of Private Tor Networks



I love it!  Nice work Karsten!


On Mon, May 19, 2008 at 2:53 PM, Karsten Loesing <karsten.loesing@xxxxxxx> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Nick,


| What about having a preprocessing step on the options list that
| expands PrivateTorNetwork 1 into the entire list of options it
| implies? It's not an error to specify an option twice; when you do,
| the second takes precedence.

Hmm, I couldn't find the right place in the code to implement your idea.
I now solved it differently: When reading configurations from torrc and
the console, Tor checks if TestingTorNetwork was configured. If so,
default values for dependent options are changed and the configuration
is read in again. See lines 3835--3892 in config.c.

I also added a hook that prevents TestingTorNetwork from being changed
after Tor is started. I could not imagine why this would be useful, and
therefore excluded this possibility to prevent unforeseen errors. See
lines 3463--3468 in config.c.


| This would mean that RESETCONF wouldn't do the right thing, though.
| Perhaps a hack like the one in weasel's debian-tor user patch would
| handle that better.  It's still a hack, but not a totally insane hack.

Right, that's what I've done now.


In the proposal I added a section with test cases. These include all
those scenarios about changing configurations that came to my mind.
These tests succeeded in a patched Tor and worked fine with a patched
PuppeTor using v3 directories.


- --Karsten
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIMfbI0M+WPffBEmURAkHJAJ4pr9yyJ0I9p/iyGbMtHn0cCz3pnACfYy6h
UNzjTYAbHyq4l25rd654+dM=
=PYOt
-----END PGP SIGNATURE-----

Index: /home/karsten/tor/tor-trunk-private-network/src/or/config.c
===================================================================
--- /home/karsten/tor/tor-trunk-private-network/src/or/config.c (revision 14671)
+++ /home/karsten/tor/tor-trunk-private-network/src/or/config.c (working copy)
@@ -174,6 +174,7 @@
  V(DataDirectory,               STRING,   NULL),
  OBSOLETE("DebugLogFile"),
  V(DirAllowPrivateAddresses,    BOOL,     NULL),
+  V(DirTimeToLearnReachability,  INTERVAL, "30 minutes"),
  V(DirListenAddress,            LINELIST, NULL),
  OBSOLETE("DirFetchPeriod"),
  V(DirPolicy,                   LINELIST, NULL),
@@ -185,6 +186,7 @@
  V(DownloadExtraInfo,           BOOL,     "0"),
  V(EnforceDistinctSubnets,      BOOL,     "1"),
  V(EntryNodes,                  STRING,   NULL),
+  V(EstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
  V(ExcludeNodes,                STRING,   NULL),
  V(ExitNodes,                   STRING,   NULL),
  V(ExitPolicy,                  LINELIST, NULL),
@@ -243,6 +245,7 @@
  V(OutboundBindAddress,         STRING,   NULL),
  OBSOLETE("PathlenCoinWeight"),
  V(PidFile,                     STRING,   NULL),
+  V(TestingTorNetwork,           BOOL,     "0"),
  V(PreferTunneledDirConns,      BOOL,     "1"),
  V(ProtocolWarnings,            BOOL,     "0"),
  V(PublishServerDescriptor,     CSV,      "1"),
@@ -297,6 +300,9 @@
  VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir,   "0"),
  VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir,   "0"),
  VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir,   "0"),
+  V(V3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
+  V(V3AuthInitialVoteDelay,      INTERVAL, "5 minutes"),
+  V(V3AuthInitialDistDelay,      INTERVAL, "5 minutes"),
  V(V3AuthVotingInterval,        INTERVAL, "1 hour"),
  V(V3AuthVoteDelay,             INTERVAL, "5 minutes"),
  V(V3AuthDistDelay,             INTERVAL, "5 minutes"),
@@ -3325,6 +3331,72 @@
    });
  }

+  if (options->TestingTorNetwork && !options->DirServers) {
+    REJECT("TestingTorNetwork may only be configured in combination with "
+           "a non-default set of DirServers.");
+  }
+
+  if (options->V3AuthInitialVotingInterval != 30*60 &&
+      !options->TestingTorNetwork) {
+    REJECT("V3AuthInitialVotingInterval may only be changed in testing "
+           "Tor networks!");
+  } else if (options->V3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
+    REJECT("V3AuthInitialVotingInterval is insanely low.");
+  } else if (options->V3AuthInitialVotingInterval > 24*60*60) {
+    REJECT("V3AuthInitialVotingInterval is insanely high.");
+  } else if (((30*60) % options->V3AuthInitialVotingInterval) != 0) {
+    REJECT("V3AuthInitialVotingInterval does not divide evenly into "
+           "30 minutes.");
+  }
+
+  if (options->V3AuthInitialVoteDelay != 5*60 &&
+      !options->TestingTorNetwork) {
+    REJECT("V3AuthInitialVoteDelay may only be changed in testing "
+           "Tor networks!");
+  } else if (options->V3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
+    REJECT("V3AuthInitialVoteDelay is way too low.");
+  }
+
+  if (options->V3AuthInitialDistDelay != 5*60 &&
+      !options->TestingTorNetwork) {
+    REJECT("V3AuthInitialDistDelay may only be changed in testing "
+           "Tor networks!");
+  } else if (options->V3AuthInitialDistDelay < MIN_DIST_SECONDS) {
+    REJECT("V3AuthInitialDistDelay is way too low.");
+  }
+
+  if (options->V3AuthInitialVoteDelay + options->V3AuthInitialDistDelay >=
+      options->V3AuthInitialVotingInterval/2) {
+    REJECT("V3AuthInitialVoteDelay plus V3AuthInitialDistDelay must be "
+           "less than half V3AuthInitialVotingInterval");
+  }
+
+  if (options->DirTimeToLearnReachability != 30*60 && !options->TestingTorNetwork) {
+    REJECT("DirTimeToLearnReachability may only be changed in testing "
+           "Tor networks!");
+  } else if (options->DirTimeToLearnReachability < 0) {
+    REJECT("DirTimeToLearnReachability must be non-negative.");
+  } else if (options->DirTimeToLearnReachability > 2*60*60) {
+    COMPLAIN("DirTimeToLearnReachability is insanely high.");
+  }
+
+  if (options->EstimatedDescriptorPropagationTime != 10*60 &&
+      !options->TestingTorNetwork) {
+    REJECT("EstimatedDescriptorPropagationTime may only be changed in "
+           "testing Tor networks!");
+  } else if (options->EstimatedDescriptorPropagationTime < 0) {
+    REJECT("EstimatedDescriptorPropagationTime must be non-negative.");
+  } else if (options->EstimatedDescriptorPropagationTime > 60*60) {
+    COMPLAIN("EstimatedDescriptorPropagationTime is insanely high.");
+  }
+
+  if (options->TestingTorNetwork) {
+    log_warn(LD_CONFIG, "TestingTorNetwork is set. This will make your node "
+                        "almost unusable in the public Tor network, and is "
+                        "therefore only advised if you are building a "
+                        "testing Tor network!");
+  }
+
  return 0;
 #undef REJECT
 #undef COMPLAIN
@@ -3388,6 +3460,12 @@
    return -1;
  }

+  if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
+    *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
+                      "is not allowed.");
+    return -1;
+  }
+
  return 0;
 }

@@ -3756,6 +3834,64 @@
    goto err;
  }

+  /* If this is a testing network configuration, change defaults
+   * for a list of dependent config options, re-initialize newoptions
+   * with the new defaults, and assign all options to it second time. */
+  if (newoptions->TestingTorNetwork) {
+
+    /* Change defaults. */
+    #define CHANGE_DEFAULT(key, val)                                \
+    {                                                               \
+      config_var_t *var = config_find_option(&options_format, key); \
+      tor_assert(var);                                              \
+      var->initvalue = tor_strdup(val);                             \
+    }
+    CHANGE_DEFAULT("ServerDNSAllowBrokenResolvConf", "1");
+    CHANGE_DEFAULT("DirAllowPrivateAddresses", "1");
+    CHANGE_DEFAULT("EnforceDistinctSubnets", "0");
+    CHANGE_DEFAULT("AssumeReachable", "1");
+    CHANGE_DEFAULT("AuthDirMaxServersPerAddr", "0");
+    CHANGE_DEFAULT("AuthDirMaxServersPerAuthAddr", "0");
+    CHANGE_DEFAULT("ClientDNSRejectInternalAddresses", "0");
+    CHANGE_DEFAULT("ExitPolicyRejectPrivate", "0");
+    CHANGE_DEFAULT("V3AuthVotingInterval", "300");
+    CHANGE_DEFAULT("V3AuthVoteDelay", "20");
+    CHANGE_DEFAULT("V3AuthDistDelay", "20");
+    CHANGE_DEFAULT("V3AuthInitialVotingInterval", "300");
+    CHANGE_DEFAULT("V3AuthInitialVoteDelay", "20");
+    CHANGE_DEFAULT("V3AuthInitialDistDelay", "20");
+    CHANGE_DEFAULT("DirTimeToLearnReachability", "0");
+    CHANGE_DEFAULT("EstimatedDescriptorPropagationTime", "0");
+    #undef CHANGE_DEFAULT
+
+    /* Clear newoptions and re-initialize them with new defaults. */
+    config_free(&options_format, newoptions);
+    newoptions = tor_malloc_zero(sizeof(or_options_t));
+    newoptions->_magic = OR_OPTIONS_MAGIC;
+    options_init(newoptions);
+    newoptions->command = command;
+    newoptions->command_arg = command_arg;
+
+    /* Assign all options a second time. */
+    retval = config_get_lines(cf, &cl);
+    if (retval < 0) {
+      err = SETOPT_ERR_PARSE;
+      goto err;
+    }
+    retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
+    config_free_lines(cl);
+    if (retval < 0) {
+      err = SETOPT_ERR_PARSE;
+      goto err;
+    }
+    retval = config_assign(&options_format, newoptions,
+                           global_cmdline_options, 0, 0, msg);
+    if (retval < 0) {
+      err = SETOPT_ERR_PARSE;
+      goto err;
+    }
+  }
+
  /* Validate newoptions */
  if (options_validate(oldoptions, newoptions, 0, msg) < 0) {
    err = SETOPT_ERR_PARSE; /*XXX021 make this separate.*/
Index: /home/karsten/tor/tor-trunk-private-network/src/or/dirserv.c
===================================================================
--- /home/karsten/tor/tor-trunk-private-network/src/or/dirserv.c        (revision 14671)
+++ /home/karsten/tor/tor-trunk-private-network/src/or/dirserv.c        (working copy)
@@ -2122,10 +2122,6 @@
    router->is_bad_exit = router->is_bad_directory = 0;
 }

-/** If we've been around for less than this amount of time, our reachability
- * information is not accurate. */
-#define DIRSERV_TIME_TO_GET_REACHABILITY_INFO (30*60)
-
 /** Return a new networkstatus_t* containing our current opinion. (For v3
 * authorities) */
 networkstatus_t *
@@ -2155,7 +2151,7 @@
  tor_assert(private_key);
  tor_assert(cert);

-  if (now - time_of_process_start < DIRSERV_TIME_TO_GET_REACHABILITY_INFO)
+  if (now - time_of_process_start < options->DirTimeToLearnReachability)
    vote_on_reachability = 0;

  if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
@@ -2241,7 +2237,7 @@
      last_consensus_interval = current_consensus->fresh_until -
        current_consensus->valid_after;
    else
-      last_consensus_interval = DEFAULT_VOTING_INTERVAL_WHEN_NO_CONSENSUS;
+      last_consensus_interval = options->V3AuthInitialVotingInterval;
    v3_out->valid_after =
      dirvote_get_start_of_next_interval(now, (int)last_consensus_interval);
    format_iso_time(tbuf, v3_out->valid_after);
Index: /home/karsten/tor/tor-trunk-private-network/src/or/dirvote.c
===================================================================
--- /home/karsten/tor/tor-trunk-private-network/src/or/dirvote.c        (revision 14671)
+++ /home/karsten/tor/tor-trunk-private-network/src/or/dirvote.c        (working copy)
@@ -1300,8 +1300,9 @@
    vote_delay = consensus->vote_seconds;
    dist_delay = consensus->dist_seconds;
  } else {
-    interval = DEFAULT_VOTING_INTERVAL_WHEN_NO_CONSENSUS;
-    vote_delay = dist_delay = 300;
+    interval = options->V3AuthInitialVotingInterval;
+    vote_delay = options->V3AuthInitialVoteDelay;
+    dist_delay = options->V3AuthInitialDistDelay;
  }

  tor_assert(interval > 0);
Index: /home/karsten/tor/tor-trunk-private-network/src/or/or.h
===================================================================
--- /home/karsten/tor/tor-trunk-private-network/src/or/or.h     (revision 14671)
+++ /home/karsten/tor/tor-trunk-private-network/src/or/or.h     (working copy)
@@ -2344,6 +2344,31 @@
   * migration purposes? */
  int V3AuthUseLegacyKey;

+  /** The length of time that we think an initial consensus should be
+   * fresh. */
+  int V3AuthInitialVotingInterval;
+
+  /** The length of time we think it will take to distribute initial
+   * votes. */
+  int V3AuthInitialVoteDelay;
+
+  /** The length of time we think it will take to distribute initial
+   * signatures. */
+  int V3AuthInitialDistDelay;
+
+  /** If an authority has been around for less than this amount of time,
+   * its reachability information is not accurate. */
+  int DirTimeToLearnReachability;
+
+  /** Clients don't download any descriptor this recent, since it will
+   * probably not have propagated to enough caches. */
+  int EstimatedDescriptorPropagationTime;
+
+  /** If true, we take part in a testing network. Change the defaults of a
+   * couple of other configuration options and allow to change the values
+   * of certain configuration options. */
+  int TestingTorNetwork;
+
  /** File to check for a consensus networkstatus, if we don't have one
   * cached. */
  char *FallbackNetworkstatusFile;
@@ -3186,9 +3211,6 @@
 /** Smallest allowable voting interval. */
 #define MIN_VOTE_INTERVAL 300

-/** If there is no consensus, what interval do we default to? */
-#define DEFAULT_VOTING_INTERVAL_WHEN_NO_CONSENSUS (30*60)
-
 void dirvote_free_all(void);

 /* vote manipulation */
Index: /home/karsten/tor/tor-trunk-private-network/src/or/routerlist.c
===================================================================
--- /home/karsten/tor/tor-trunk-private-network/src/or/routerlist.c     (revision 14671)
+++ /home/karsten/tor/tor-trunk-private-network/src/or/routerlist.c     (working copy)
@@ -3673,10 +3673,6 @@
  tor_free(resource);
 }

-/** Clients don't download any descriptor this recent, since it will probably
- * not have propagated to enough caches. */
-#define ESTIMATED_PROPAGATION_TIME (10*60)
-
 /** Return 0 if this routerstatus is obsolete, too new, isn't
 * running, or otherwise not a descriptor that we would make any
 * use of even if we had it. Else return 1. */
@@ -3688,7 +3684,7 @@
     * But, if we want to have a complete list, fetch it anyway. */
    return 0;
  }
-  if (rs->published_on + ESTIMATED_PROPAGATION_TIME > now) {
+  if (rs->published_on + options->EstimatedDescriptorPropagationTime > now) {
    /* Most caches probably don't have this descriptor yet. */
    return 0;
  }