[tor-commits] [tor/master] Merge remote branch 'origin/maint-0.2.2'

nickm at torproject.org nickm at torproject.org
Tue Mar 8 21:20:38 UTC 2011


commit 63651b919183e1b0a126109646030aca975344bd
Merge: cb3c3c6 0044697
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Mar 8 16:20:53 2011 -0500

    Merge remote branch 'origin/maint-0.2.2'
    
    Trivial conflicts fixed in or.h
    
    Conflicts:
    	src/or/or.h

 changes/bug2250 |    5 +++++
 src/or/config.c |   13 ++++++++-----
 src/or/or.h     |    5 +++++
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --combined src/or/config.c
index 769831b,d4be207..79d222b
--- a/src/or/config.c
+++ b/src/or/config.c
@@@ -44,8 -44,6 +44,8 @@@ typedef enum config_type_t 
    CONFIG_TYPE_FILENAME,     /**< A filename: some prefixes get expanded. */
    CONFIG_TYPE_UINT,         /**< A non-negative integer less than MAX_INT */
    CONFIG_TYPE_INTERVAL,     /**< A number of seconds, with optional units*/
 +  CONFIG_TYPE_MSEC_INTERVAL,/**< A number of milliseconds, with optional
 +                              * units */
    CONFIG_TYPE_MEMUNIT,      /**< A number of bytes, with optional units*/
    CONFIG_TYPE_DOUBLE,       /**< A floating-point value */
    CONFIG_TYPE_BOOL,         /**< A boolean value, expressed as 0 or 1. */
@@@ -201,7 -199,6 +201,7 @@@ static config_var_t _option_vars[] = 
    V(ClientOnly,                  BOOL,     "0"),
    V(ConsensusParams,             STRING,   NULL),
    V(ConnLimit,                   UINT,     "1000"),
 +  V(ConnDirectionStatistics,     BOOL,     "0"),
    V(ConstrainedSockets,          BOOL,     "0"),
    V(ConstrainedSockSize,         MEMUNIT,  "8192"),
    V(ContactInfo,                 STRING,   NULL),
@@@ -225,10 -222,9 +225,10 @@@
    OBSOLETE("DirRecordUsageGranularity"),
    OBSOLETE("DirRecordUsageRetainIPs"),
    OBSOLETE("DirRecordUsageSaveInterval"),
 -  V(DirReqStatistics,            BOOL,     "0"),
 +  V(DirReqStatistics,            BOOL,     "1"),
    VAR("DirServer",               LINELIST, DirServers, NULL),
    V(DisableAllSwap,              BOOL,     "0"),
 +  V(DisableIOCP,                 BOOL,     "1"),
    V(DNSPort,                     UINT,     "0"),
    V(DNSListenAddress,            LINELIST, NULL),
    V(DownloadExtraInfo,           BOOL,     "0"),
@@@ -243,7 -239,7 +243,7 @@@
    V(ExitPolicy,                  LINELIST, NULL),
    V(ExitPolicyRejectPrivate,     BOOL,     "1"),
    V(ExitPortStatistics,          BOOL,     "0"),
 -  V(ExtraInfoStatistics,         BOOL,     "0"),
 +  V(ExtraInfoStatistics,         BOOL,     "1"),
  
  #if defined (WINCE)
    V(FallbackNetworkstatusFile,   FILENAME, "fallback-consensus"),
@@@ -267,7 -263,6 +267,7 @@@
  #endif
    OBSOLETE("Group"),
    V(HardwareAccel,               BOOL,     "0"),
 +  V(HeartbeatPeriod,             INTERVAL, "6 hours"),
    V(AccelName,                   STRING,   NULL),
    V(AccelDir,                    FILENAME, NULL),
    V(HashedControlPassword,       LINELIST, NULL),
@@@ -297,7 -292,6 +297,7 @@@
    OBSOLETE("LinkPadding"),
    OBSOLETE("LogLevel"),
    OBSOLETE("LogFile"),
 +  V(LogTimeGranularity,          MSEC_INTERVAL, "1 second"),
    V(LongLivedPorts,              CSV,
                           "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
    VAR("MapAddress",              LINELIST, AddressMap,           NULL),
@@@ -314,7 -308,7 +314,7 @@@
    V(WarnUnsafeSocks,              BOOL,     "1"),
    OBSOLETE("NoPublish"),
    VAR("NodeFamily",              LINELIST, NodeFamilies,         NULL),
 -  V(NumCPUs,                     UINT,     "1"),
 +  V(NumCPUs,                     UINT,     "0"),
    V(NumEntryGuards,              UINT,     "3"),
    V(ORListenAddress,             LINELIST, NULL),
    V(ORPort,                      UINT,     "0"),
@@@ -324,8 -318,6 +324,8 @@@
    V(PerConnBWRate,               MEMUNIT,  "0"),
    V(PidFile,                     STRING,   NULL),
    V(TestingTorNetwork,           BOOL,     "0"),
 +  V(PortForwarding,              BOOL,     "0"),
 +  V(PortForwardingHelper,        FILENAME, "tor-fw-helper"),
    V(PreferTunneledDirConns,      BOOL,     "1"),
    V(ProtocolWarnings,            BOOL,     "0"),
    V(PublishServerDescriptor,     CSV,      "1"),
@@@ -394,7 -386,6 +394,7 @@@
    VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
    V(VirtualAddrNetwork,          STRING,   "127.192.0.0/10"),
    V(WarnPlaintextPorts,          CSV,      "23,109,110,143"),
 +  V(_UseFilteringSSLBufferevents, BOOL,    "0"),
    VAR("__ReloadTorrcOnSIGHUP",   BOOL,  ReloadTorrcOnSIGHUP,      "1"),
    VAR("__AllDirActionsPrivate",  BOOL,  AllDirActionsPrivate,     "0"),
    VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
@@@ -402,6 -393,7 +402,7 @@@
    VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
        NULL),
    V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"),
+   V(_UsingTestNetworkDefaults,   BOOL,     "0"),
  
    { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
  };
@@@ -427,6 -419,7 +428,7 @@@ static config_var_t testing_tor_network
    V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
    V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
    V(MinUptimeHidServDirectoryV2, INTERVAL, "0 minutes"),
+   V(_UsingTestNetworkDefaults,   BOOL,     "1"),
    { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
  };
  #undef VAR
@@@ -571,9 -564,8 +573,9 @@@ static int is_listening_on_low_port(uin
                                      const config_line_t *listen_options);
  
  static uint64_t config_parse_memunit(const char *s, int *ok);
 +static int config_parse_msec_interval(const char *s, int *ok);
  static int config_parse_interval(const char *s, int *ok);
 -static void init_libevent(void);
 +static void init_libevent(const or_options_t *options);
  static int opt_streq(const char *s1, const char *s2);
  
  /** Magic value for or_options_t. */
@@@ -707,11 -699,6 +709,11 @@@ or_options_free(or_options_t *options
      return;
  
    routerset_free(options->_ExcludeExitNodesUnion);
 +  if (options->NodeFamilySets) {
 +    SMARTLIST_FOREACH(options->NodeFamilySets, routerset_t *,
 +                      rs, routerset_free(rs));
 +    smartlist_free(options->NodeFamilySets);
 +  }
    config_free(&options_format, options);
  }
  
@@@ -979,7 -966,7 +981,7 @@@ options_act_reversible(or_options_t *ol
      /* Set up libevent.  (We need to do this before we can register the
       * listeners as listeners.) */
      if (running_tor && !libevent_initialized) {
 -      init_libevent();
 +      init_libevent(options);
        libevent_initialized = 1;
      }
  
@@@ -1255,17 -1242,6 +1257,17 @@@ options_act(or_options_t *old_options
    if (accounting_is_enabled(options))
      configure_accounting(time(NULL));
  
 +#ifdef USE_BUFFEREVENTS
 +  /* If we're using the bufferevents implementation and our rate limits
 +   * changed, we need to tell the rate-limiting system about it. */
 +  if (!old_options ||
 +      old_options->BandwidthRate != options->BandwidthRate ||
 +      old_options->BandwidthBurst != options->BandwidthBurst ||
 +      old_options->RelayBandwidthRate != options->RelayBandwidthRate ||
 +      old_options->RelayBandwidthBurst != options->RelayBandwidthBurst)
 +    connection_bucket_init();
 +#endif
 +
    /* parse RefuseUnknownExits tristate */
    if (!strcmp(options->RefuseUnknownExits, "0"))
      options->RefuseUnknownExits_ = 0;
@@@ -1377,54 -1353,44 +1379,54 @@@
      tor_free(actual_fname);
    }
  
 -  if (options->DirReqStatistics && !geoip_is_loaded()) {
 -    /* Check if GeoIP database could be loaded. */
 -    log_warn(LD_CONFIG, "Configured to measure directory request "
 -             "statistics, but no GeoIP database found!");
 -    return -1;
 -  }
 -
 -  if (options->EntryStatistics) {
 -    if (should_record_bridge_info(options)) {
 -      /* Don't allow measuring statistics on entry guards when configured
 -       * as bridge. */
 -      log_warn(LD_CONFIG, "Bridges cannot be configured to measure "
 -               "additional GeoIP statistics as entry guards.");
 -      return -1;
 -    } else if (!geoip_is_loaded()) {
 -      /* Check if GeoIP database could be loaded. */
 -      log_warn(LD_CONFIG, "Configured to measure entry node statistics, "
 -               "but no GeoIP database found!");
 -      return -1;
 -    }
 -  }
 -
    if (options->CellStatistics || options->DirReqStatistics ||
 -      options->EntryStatistics || options->ExitPortStatistics) {
 +      options->EntryStatistics || options->ExitPortStatistics ||
 +      options->ConnDirectionStatistics) {
      time_t now = time(NULL);
 +    int print_notice = 0;
      if ((!old_options || !old_options->CellStatistics) &&
 -        options->CellStatistics)
 +        options->CellStatistics) {
        rep_hist_buffer_stats_init(now);
 +      print_notice = 1;
 +    }
      if ((!old_options || !old_options->DirReqStatistics) &&
 -        options->DirReqStatistics)
 -      geoip_dirreq_stats_init(now);
 +        options->DirReqStatistics) {
 +      if (geoip_is_loaded()) {
 +        geoip_dirreq_stats_init(now);
 +        print_notice = 1;
 +      } else {
 +        options->DirReqStatistics = 0;
 +        /* Don't warn Tor clients, they don't use statistics */
 +        if (options->ORPort)
 +          log_notice(LD_CONFIG, "Configured to measure directory request "
 +                                "statistics, but no GeoIP database found. "
 +                                "Please specify a GeoIP database using the "
 +                                "GeoIPFile option.");
 +      }
 +    }
      if ((!old_options || !old_options->EntryStatistics) &&
 -        options->EntryStatistics)
 -      geoip_entry_stats_init(now);
 +        options->EntryStatistics && !should_record_bridge_info(options)) {
 +      if (geoip_is_loaded()) {
 +        geoip_entry_stats_init(now);
 +        print_notice = 1;
 +      } else {
 +        options->EntryStatistics = 0;
 +        log_notice(LD_CONFIG, "Configured to measure entry node "
 +                              "statistics, but no GeoIP database found. "
 +                              "Please specify a GeoIP database using the "
 +                              "GeoIPFile option.");
 +      }
 +    }
      if ((!old_options || !old_options->ExitPortStatistics) &&
 -        options->ExitPortStatistics)
 +        options->ExitPortStatistics) {
        rep_hist_exit_stats_init(now);
 -    if (!old_options)
 +      print_notice = 1;
 +    }
 +    if ((!old_options || !old_options->ConnDirectionStatistics) &&
 +        options->ConnDirectionStatistics) {
 +      rep_hist_conn_stats_init(now);
 +    }
 +    if (print_notice)
        log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
                   "the *-stats files that will first be written to the "
                   "data directory in 24 hours from now.");
@@@ -1442,9 -1408,6 +1444,9 @@@
    if (old_options && old_options->ExitPortStatistics &&
        !options->ExitPortStatistics)
      rep_hist_exit_stats_term();
 +  if (old_options && old_options->ConnDirectionStatistics &&
 +      !options->ConnDirectionStatistics)
 +    rep_hist_conn_stats_term();
  
    /* Check if we need to parse and add the EntryNodes config option. */
    if (options->EntryNodes &&
@@@ -1750,18 -1713,6 +1752,18 @@@ config_assign_value(config_format_t *fm
      break;
    }
  
 +  case CONFIG_TYPE_MSEC_INTERVAL: {
 +    i = config_parse_msec_interval(c->value, &ok);
 +    if (!ok) {
 +      tor_asprintf(msg,
 +          "Msec interval '%s %s' is malformed or out of bounds.",
 +          c->key, c->value);
 +      return -1;
 +    }
 +    *(int *)lvalue = i;
 +    break;
 +  }
 +
    case CONFIG_TYPE_MEMUNIT: {
      uint64_t u64 = config_parse_memunit(c->value, &ok);
      if (!ok) {
@@@ -2049,7 -2000,6 +2051,7 @@@ get_assigned_option(config_format_t *fm
        escape_val = 0; /* Can't need escape. */
        break;
      case CONFIG_TYPE_INTERVAL:
 +    case CONFIG_TYPE_MSEC_INTERVAL:
      case CONFIG_TYPE_UINT:
        /* This means every or_options_t uint or bool element
         * needs to be an int. Not, say, a uint16_t or char. */
@@@ -2277,7 -2227,6 +2279,7 @@@ option_clear(config_format_t *fmt, or_o
        *(time_t*)lvalue = 0;
        break;
      case CONFIG_TYPE_INTERVAL:
 +    case CONFIG_TYPE_MSEC_INTERVAL:
      case CONFIG_TYPE_UINT:
      case CONFIG_TYPE_BOOL:
        *(int*)lvalue = 0;
@@@ -2384,7 -2333,7 +2386,7 @@@ resolve_my_address(int warn_severity, o
    int explicit_ip=1;
    int explicit_hostname=1;
    int from_interface=0;
 -  char tmpbuf[INET_NTOA_BUF_LEN];
 +  char *addr_string = NULL;
    const char *address = options->Address;
    int notice_severity = warn_severity <= LOG_NOTICE ?
                            LOG_NOTICE : warn_severity;
@@@ -2426,43 -2375,48 +2428,43 @@@
          return -1;
        }
        from_interface = 1;
 -      in.s_addr = htonl(interface_ip);
 -      tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
 +      addr = interface_ip;
        log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
 -             "local interface. Using that.", tmpbuf);
 +             "local interface. Using that.", fmt_addr32(addr));
        strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
      } else { /* resolved hostname into addr */
 -      in.s_addr = htonl(addr);
 -
        if (!explicit_hostname &&
 -          is_internal_IP(ntohl(in.s_addr), 0)) {
 +          is_internal_IP(addr, 0)) {
          uint32_t interface_ip;
  
 -        tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
          log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
 -               "resolves to a private IP address (%s).  Trying something "
 -               "else.", hostname, tmpbuf);
 +               "resolves to a private IP address (%s). Trying something "
 +               "else.", hostname, fmt_addr32(addr));
  
          if (get_interface_address(warn_severity, &interface_ip)) {
            log_fn(warn_severity, LD_CONFIG,
                   "Could not get local interface IP address. Too bad.");
          } else if (is_internal_IP(interface_ip, 0)) {
 -          struct in_addr in2;
 -          in2.s_addr = htonl(interface_ip);
 -          tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
            log_fn(notice_severity, LD_CONFIG,
                   "Interface IP address '%s' is a private address too. "
 -                 "Ignoring.", tmpbuf);
 +                 "Ignoring.", fmt_addr32(interface_ip));
          } else {
            from_interface = 1;
 -          in.s_addr = htonl(interface_ip);
 -          tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
 +          addr = interface_ip;
            log_fn(notice_severity, LD_CONFIG,
                   "Learned IP address '%s' for local interface."
 -                 " Using that.", tmpbuf);
 +                 " Using that.", fmt_addr32(addr));
            strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
          }
        }
      }
 +  } else {
 +    addr = ntohl(in.s_addr); /* set addr so that addr_string is not
 +                              * illformed */
    }
  
 -  tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
 -  if (is_internal_IP(ntohl(in.s_addr), 0)) {
 +  addr_string = tor_dup_ip(addr);
 +  if (is_internal_IP(addr, 0)) {
      /* make sure we're ok with publishing an internal IP */
      if (!options->DirServers && !options->AlternateDirAuthority) {
        /* if they are using the default dirservers, disallow internal IPs
@@@ -2470,8 -2424,7 +2472,8 @@@
        log_fn(warn_severity, LD_CONFIG,
               "Address '%s' resolves to private IP address '%s'. "
               "Tor servers that use the default DirServers must have public "
 -             "IP addresses.", hostname, tmpbuf);
 +             "IP addresses.", hostname, addr_string);
 +      tor_free(addr_string);
        return -1;
      }
      if (!explicit_ip) {
@@@ -2479,20 -2432,19 +2481,20 @@@
         * they're using an internal address. */
        log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
               "IP address '%s'. Please set the Address config option to be "
 -             "the IP address you want to use.", hostname, tmpbuf);
 +             "the IP address you want to use.", hostname, addr_string);
 +      tor_free(addr_string);
        return -1;
      }
    }
  
 -  log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
 -  *addr_out = ntohl(in.s_addr);
 +  log_debug(LD_CONFIG, "Resolved Address to '%s'.", fmt_addr32(addr));
 +  *addr_out = addr;
    if (last_resolved_addr && last_resolved_addr != *addr_out) {
      /* Leave this as a notice, regardless of the requested severity,
       * at least until dynamic IP address support becomes bulletproof. */
      log_notice(LD_NET,
                 "Your IP address seems to have changed to %s. Updating.",
 -               tmpbuf);
 +               addr_string);
      ip_address_changed(0);
    }
    if (last_resolved_addr != *addr_out) {
@@@ -2511,12 -2463,11 +2513,12 @@@
      }
      control_event_server_status(LOG_NOTICE,
                                  "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
 -                                tmpbuf, method, h?"HOSTNAME=":"", h);
 +                                addr_string, method, h?"HOSTNAME=":"", h);
    }
    last_resolved_addr = *addr_out;
    if (hostname_out)
      *hostname_out = tor_strdup(hostname);
 +  tor_free(addr_string);
    return 0;
  }
  
@@@ -2923,10 -2874,6 +2925,10 @@@ compute_publishserverdescriptor(or_opti
   * will generate too many circuits and potentially overload the network. */
  #define MIN_CIRCUIT_STREAM_TIMEOUT 10
  
 +/** Lowest allowable value for HeartbeatPeriod; if this is too low, we might
 + * expose more information than we're comfortable with. */
 +#define MIN_HEARTBEAT_PERIOD (30*60)
 +
  /** Return 0 if every setting in <b>options</b> is reasonable, and a
   * permissible transition from <b>old_options</b>. Else return -1.
   * Should have no side effects, except for normalizing the contents of
@@@ -3127,24 -3074,17 +3129,24 @@@ options_validate(or_options_t *old_opti
      routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
    }
  
 +  if (options->NodeFamilies) {
 +    options->NodeFamilySets = smartlist_create();
 +    for (cl = options->NodeFamilies; cl; cl = cl->next) {
 +      routerset_t *rs = routerset_new();
 +      if (routerset_parse(rs, cl->value, cl->key) == 0) {
 +        smartlist_add(options->NodeFamilySets, rs);
 +      } else {
 +        routerset_free(rs);
 +      }
 +    }
 +  }
 +
    if (options->ExcludeNodes && options->StrictNodes) {
      COMPLAIN("You have asked to exclude certain relays from all positions "
               "in your circuits. Expect hidden services and other Tor "
               "features to be broken in unpredictable ways.");
    }
  
 -  if (options->EntryNodes && !routerset_is_list(options->EntryNodes)) {
 -    /* XXXX fix this; see entry_guards_prepend_from_config(). */
 -    REJECT("IPs or countries are not yet supported in EntryNodes.");
 -  }
 -
    if (options->AuthoritativeDir) {
      if (!options->ContactInfo && !options->TestingTorNetwork)
        REJECT("Authoritative directory servers must set ContactInfo");
@@@ -3389,13 -3329,6 +3391,13 @@@
      options->CircuitStreamTimeout = MIN_CIRCUIT_STREAM_TIMEOUT;
    }
  
 +  if (options->HeartbeatPeriod &&
 +      options->HeartbeatPeriod < MIN_HEARTBEAT_PERIOD) {
 +    log_warn(LD_CONFIG, "HeartbeatPeriod option is too short; "
 +             "raising to %d seconds.", MIN_HEARTBEAT_PERIOD);
 +    options->HeartbeatPeriod = MIN_HEARTBEAT_PERIOD;
 +  }
 +
    if (options->KeepalivePeriod < 1)
      REJECT("KeepalivePeriod option must be positive.");
  
@@@ -3614,12 -3547,8 +3616,12 @@@
    if (check_nickname_list(options->MyFamily, "MyFamily", msg))
      return -1;
    for (cl = options->NodeFamilies; cl; cl = cl->next) {
 -    if (check_nickname_list(cl->value, "NodeFamily", msg))
 +    routerset_t *rs = routerset_new();
 +    if (routerset_parse(rs, cl->value, cl->key)) {
 +      routerset_free(rs);
        return -1;
 +    }
 +    routerset_free(rs);
    }
  
    if (validate_addr_policies(options, msg) < 0)
@@@ -3728,7 -3657,7 +3730,7 @@@
    /* Keep changes to hard-coded values synchronous to man page and default
     * values table. */
    if (options->TestingV3AuthInitialVotingInterval != 30*60 &&
-       !options->TestingTorNetwork) {
+       !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
      REJECT("TestingV3AuthInitialVotingInterval may only be changed in testing "
             "Tor networks!");
    } else if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
@@@ -3739,7 -3668,8 +3741,8 @@@
    }
  
    if (options->TestingV3AuthInitialVoteDelay != 5*60 &&
-       !options->TestingTorNetwork) {
+       !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
+ 
      REJECT("TestingV3AuthInitialVoteDelay may only be changed in testing "
             "Tor networks!");
    } else if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
@@@ -3747,7 -3677,7 +3750,7 @@@
    }
  
    if (options->TestingV3AuthInitialDistDelay != 5*60 &&
-       !options->TestingTorNetwork) {
+       !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
      REJECT("TestingV3AuthInitialDistDelay may only be changed in testing "
             "Tor networks!");
    } else if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) {
@@@ -3762,7 -3692,7 +3765,7 @@@
    }
  
    if (options->TestingAuthDirTimeToLearnReachability != 30*60 &&
-       !options->TestingTorNetwork) {
+       !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
      REJECT("TestingAuthDirTimeToLearnReachability may only be changed in "
             "testing Tor networks!");
    } else if (options->TestingAuthDirTimeToLearnReachability < 0) {
@@@ -3772,7 -3702,7 +3775,7 @@@
    }
  
    if (options->TestingEstimatedDescriptorPropagationTime != 10*60 &&
-       !options->TestingTorNetwork) {
+       !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
      REJECT("TestingEstimatedDescriptorPropagationTime may only be changed in "
             "testing Tor networks!");
    } else if (options->TestingEstimatedDescriptorPropagationTime < 0) {
@@@ -4113,8 -4043,6 +4116,8 @@@ load_torrc_from_disk(int argc, char **a
            "Unable to open configuration file \"%s\".", fname);
        goto err;
      }
 +  } else {
 +    log(LOG_NOTICE, LD_CONFIG, "Read configuration file \"%s\".", fname);
    }
  
    return cf;
@@@ -4403,35 -4331,6 +4406,35 @@@ options_init_logs(or_options_t *options
                 options->RunAsDaemon;
  #endif
  
 +  if (options->LogTimeGranularity <= 0) {
 +    log_warn(LD_CONFIG, "Log time granularity '%d' has to be positive.",
 +             options->LogTimeGranularity);
 +    return -1;
 +  } else if (1000 % options->LogTimeGranularity != 0 &&
 +             options->LogTimeGranularity % 1000 != 0) {
 +    int granularity = options->LogTimeGranularity;
 +    if (granularity < 40) {
 +      do granularity++;
 +      while (1000 % granularity != 0);
 +    } else if (granularity < 1000) {
 +      granularity = 1000 / granularity;
 +      while (1000 % granularity != 0)
 +        granularity--;
 +      granularity = 1000 / granularity;
 +    } else {
 +      granularity = 1000 * ((granularity / 1000) + 1);
 +    }
 +    log_warn(LD_CONFIG, "Log time granularity '%d' has to be either a "
 +                        "divisor or a multiple of 1 second. Changing to "
 +                        "'%d'.",
 +             options->LogTimeGranularity, granularity);
 +    if (!validate_only)
 +      set_log_time_granularity(granularity);
 +  } else {
 +    if (!validate_only)
 +      set_log_time_granularity(options->LogTimeGranularity);
 +  }
 +
    ok = 1;
    elts = smartlist_create();
  
@@@ -4923,26 -4822,6 +4926,26 @@@ static struct unit_table_t time_units[
    { NULL, 0 },
  };
  
 +/** Table to map the names of time units to the number of milliseconds
 + * they contain. */
 +static struct unit_table_t time_msec_units[] = {
 +  { "",         1 },
 +  { "msec",     1 },
 +  { "millisecond", 1 },
 +  { "milliseconds", 1 },
 +  { "second",   1000 },
 +  { "seconds",  1000 },
 +  { "minute",   60*1000 },
 +  { "minutes",  60*1000 },
 +  { "hour",     60*60*1000 },
 +  { "hours",    60*60*1000 },
 +  { "day",      24*60*60*1000 },
 +  { "days",     24*60*60*1000 },
 +  { "week",     7*24*60*60*1000 },
 +  { "weeks",    7*24*60*60*1000 },
 +  { NULL, 0 },
 +};
 +
  /** Parse a string <b>val</b> containing a number, zero or more
   * spaces, and an optional unit string.  If the unit appears in the
   * table <b>u</b>, then multiply the number by the unit multiplier.
@@@ -5006,25 -4885,6 +5009,25 @@@ config_parse_memunit(const char *s, in
    return u;
  }
  
 +/** Parse a string in the format "number unit", where unit is a unit of
 + * time in milliseconds.  On success, set *<b>ok</b> to true and return
 + * the number of milliseconds in the provided interval.  Otherwise, set
 + * *<b>ok</b> to 0 and return -1. */
 +static int
 +config_parse_msec_interval(const char *s, int *ok)
 +{
 +  uint64_t r;
 +  r = config_parse_units(s, time_msec_units, ok);
 +  if (!ok)
 +    return -1;
 +  if (r > INT_MAX) {
 +    log_warn(LD_CONFIG, "Msec interval '%s' is too long", s);
 +    *ok = 0;
 +    return -1;
 +  }
 +  return (int)r;
 +}
 +
  /** Parse a string in the format "number unit", where unit is a unit of time.
   * On success, set *<b>ok</b> to true and return the number of seconds in
   * the provided interval.  Otherwise, set *<b>ok</b> to 0 and return -1.
@@@ -5044,29 -4904,13 +5047,29 @@@ config_parse_interval(const char *s, in
    return (int)r;
  }
  
 +/** Return the number of cpus configured in <b>options</b>.  If we are
 + * told to auto-detect the number of cpus, return the auto-detected number. */
 +int
 +get_num_cpus(const or_options_t *options)
 +{
 +  if (options->NumCPUs == 0) {
 +    int n = compute_num_cpus();
 +    return (n >= 1) ? n : 1;
 +  } else {
 +    return options->NumCPUs;
 +  }
 +}
 +
  /**
   * Initialize the libevent library.
   */
  static void
 -init_libevent(void)
 +init_libevent(const or_options_t *options)
  {
    const char *badness=NULL;
 +  tor_libevent_cfg cfg;
 +
 +  tor_assert(options);
  
    configure_libevent_logging();
    /* If the kernel complains that some method (say, epoll) doesn't
@@@ -5076,11 -4920,7 +5079,11 @@@
  
    tor_check_libevent_header_compatibility();
  
 -  tor_libevent_initialize();
 +  memset(&cfg, 0, sizeof(cfg));
 +  cfg.disable_iocp = options->DisableIOCP;
 +  cfg.num_cpus = get_num_cpus(options);
 +
 +  tor_libevent_initialize(&cfg);
  
    suppress_libevent_log_msg(NULL);
  
@@@ -5421,7 -5261,6 +5424,7 @@@ getinfo_helper_config(control_connectio
          case CONFIG_TYPE_FILENAME: type = "Filename"; break;
          case CONFIG_TYPE_UINT: type = "Integer"; break;
          case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
 +        case CONFIG_TYPE_MSEC_INTERVAL: type = "TimeMsecInterval"; break;
          case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
          case CONFIG_TYPE_DOUBLE: type = "Float"; break;
          case CONFIG_TYPE_BOOL: type = "Boolean"; break;
diff --combined src/or/or.h
index e033a3e,3ce1425..323c472
--- a/src/or/or.h
+++ b/src/or/or.h
@@@ -83,13 -83,6 +83,13 @@@
  #define snprintf _snprintf
  #endif
  
 +#ifdef USE_BUFFEREVENTS
 +#include <event2/bufferevent.h>
 +#include <event2/buffer.h>
 +#include <event2/util.h>
 +#endif
 +
 +#include "crypto.h"
  #include "tortls.h"
  #include "../common/torlog.h"
  #include "container.h"
@@@ -391,9 -384,7 +391,9 @@@ typedef enum 
  /** A connection to a hidden service directory server: download a v2 rendezvous
   * descriptor. */
  #define DIR_PURPOSE_FETCH_RENDDESC_V2 18
 -#define _DIR_PURPOSE_MAX 18
 +/** A connection to a directory server: download a microdescriptor. */
 +#define DIR_PURPOSE_FETCH_MICRODESC 19
 +#define _DIR_PURPOSE_MAX 19
  
  /** True iff <b>p</b> is a purpose corresponding to uploading data to a
   * directory server. */
@@@ -814,9 -805,6 +814,9 @@@ typedef enum 
   * Tor 0.1.2.x is obsolete, we can remove this. */
  #define DEFAULT_CLIENT_NICKNAME "client"
  
 +/** Name chosen by routers that don't configure nicknames */
 +#define UNNAMED_ROUTER_NICKNAME "Unnamed"
 +
  /** Number of bytes in a SOCKS4 header. */
  #define SOCKS4_NETWORK_LEN 8
  
@@@ -862,8 -850,8 +862,8 @@@ typedef struct cell_t 
  typedef struct var_cell_t {
    uint8_t command;
    circid_t circ_id;
 -  uint16_t payload_len;
 -  uint8_t payload[1];
 +  uint16_t payload_len; /**< The actual length of <b>payload</b>. */
 +  uint8_t payload[FLEXIBLE_ARRAY_MEMBER];
  } var_cell_t;
  
  /** A cell as packed for writing to the network. */
@@@ -980,7 -968,6 +980,7 @@@ typedef struct connection_t 
    /** Our socket; -1 if this connection is closed, or has no socket. */
    evutil_socket_t s;
    int conn_array_index; /**< Index into the global connection array. */
 +
    struct event *read_event; /**< Libevent event structure. */
    struct event *write_event; /**< Libevent event structure. */
    buf_t *inbuf; /**< Buffer holding data read over this connection. */
@@@ -991,11 -978,6 +991,11 @@@
                                * read? */
    time_t timestamp_lastwritten; /**< When was the last time libevent said we
                                   * could write? */
 +
 +#ifdef USE_BUFFEREVENTS
 +  struct bufferevent *bufev; /**< A Libevent buffered IO structure. */
 +#endif
 +
    time_t timestamp_created; /**< When was this connection_t created? */
  
    /* XXXX_IP6 make this IPv6-capable */
@@@ -1095,16 -1077,10 +1095,16 @@@ typedef struct or_connection_t 
    /* bandwidth* and *_bucket only used by ORs in OPEN state: */
    int bandwidthrate; /**< Bytes/s added to the bucket. (OPEN ORs only.) */
    int bandwidthburst; /**< Max bucket size for this conn. (OPEN ORs only.) */
 +#ifndef USE_BUFFEREVENTS
    int read_bucket; /**< When this hits 0, stop receiving. Every second we
                      * add 'bandwidthrate' to this, capping it at
                      * bandwidthburst. (OPEN ORs only) */
    int write_bucket; /**< When this hits 0, stop writing. Like read_bucket. */
 +#else
 +  /** DOCDOC */
 +  /* XXXX we could share this among all connections. */
 +  struct ev_token_bucket_cfg *bucket_cfg;
 +#endif
    int n_circuits; /**< How many circuits use this connection as p_conn or
                     * n_conn ? */
  
@@@ -1212,13 -1188,8 +1212,13 @@@ typedef struct edge_connection_t 
  typedef struct dir_connection_t {
    connection_t _base;
  
 -  char *requested_resource; /**< Which 'resource' did we ask the directory
 -                             * for? */
 + /** Which 'resource' did we ask the directory for? This is typically the part
 +  * of the URL string that defines, relative to the directory conn purpose,
 +  * what thing we want.  For example, in router descriptor downloads by
 +  * descriptor digest, it contains "d/", then one ore more +-separated
 +  * fingerprints.
 +  **/
 +  char *requested_resource;
    unsigned int dirconn_direct:1; /**< Is this dirconn direct, or via Tor? */
  
    /* Used only for server sides of some dir connections, to implement
@@@ -1309,51 -1280,6 +1309,51 @@@ static INLINE control_connection_t *TO_
    return DOWNCAST(control_connection_t, c);
  }
  
 +/* Conditional macros to help write code that works whether bufferevents are
 +   disabled or not.
 +
 +   We can't just write:
 +      if (conn->bufev) {
 +        do bufferevent stuff;
 +      } else {
 +        do other stuff;
 +      }
 +   because the bufferevent stuff won't even compile unless we have a fairly
 +   new version of Libevent.  Instead, we say:
 +      IF_HAS_BUFFEREVENT(conn, { do_bufferevent_stuff } );
 +   or:
 +      IF_HAS_BUFFEREVENT(conn, {
 +        do bufferevent stuff;
 +      }) ELSE_IF_NO_BUFFEREVENT {
 +        do non-bufferevent stuff;
 +      }
 +   If we're compiling with bufferevent support, then the macros expand more or
 +   less to:
 +      if (conn->bufev) {
 +        do_bufferevent_stuff;
 +      } else {
 +        do non-bufferevent stuff;
 +      }
 +   and if we aren't using bufferevents, they expand more or less to:
 +      { do non-bufferevent stuff; }
 +*/
 +#ifdef USE_BUFFEREVENTS
 +#define HAS_BUFFEREVENT(c) (((c)->bufev) != NULL)
 +#define IF_HAS_BUFFEREVENT(c, stmt)                \
 +  if ((c)->bufev) do {                             \
 +      stmt ;                                       \
 +  } while (0)
 +#define ELSE_IF_NO_BUFFEREVENT ; else
 +#define IF_HAS_NO_BUFFEREVENT(c)                   \
 +  if (NULL == (c)->bufev)
 +#else
 +#define HAS_BUFFEREVENT(c) (0)
 +#define IF_HAS_BUFFEREVENT(c, stmt) (void)0
 +#define ELSE_IF_NO_BUFFEREVENT ;
 +#define IF_HAS_NO_BUFFEREVENT(c)                \
 +  if (1)
 +#endif
 +
  /** What action type does an address policy indicate: accept or reject? */
  typedef enum {
    ADDR_POLICY_ACCEPT=1,
@@@ -1517,49 -1443,59 +1517,49 @@@ typedef struct 
    char *contact_info; /**< Declared contact info for this router. */
    unsigned int is_hibernating:1; /**< Whether the router claims to be
                                    * hibernating */
 -  unsigned int has_old_dnsworkers:1; /**< Whether the router is using
 -                                      * dnsworker code. */
 -  unsigned int caches_extra_info:1; /**< Whether the router caches and serves
 -                                     * extrainfo documents. */
 -  unsigned int allow_single_hop_exits:1;  /**< Whether the router allows
 -                                     * single hop exits. */
 -
 -  /* local info */
 -  unsigned int is_running:1; /**< As far as we know, is this OR currently
 -                              * running? */
 -  unsigned int is_valid:1; /**< Has a trusted dirserver validated this OR?
 -                               *  (For Authdir: Have we validated this OR?)
 -                               */
 -  unsigned int is_named:1; /**< Do we believe the nickname that this OR gives
 -                            * us? */
 -  unsigned int is_fast:1; /** Do we think this is a fast OR? */
 -  unsigned int is_stable:1; /** Do we think this is a stable OR? */
 -  unsigned int is_possible_guard:1; /**< Do we think this is an OK guard? */
 -  unsigned int is_exit:1; /**< Do we think this is an OK exit? */
 -  unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked,
 -                               * or otherwise nasty? */
 -  unsigned int is_bad_directory:1; /**< Do we think this directory is junky,
 -                                    * underpowered, or otherwise useless? */
 +  unsigned int caches_extra_info:1; /**< Whether the router says it caches and
 +                                     * serves extrainfo documents. */
 +  unsigned int allow_single_hop_exits:1;  /**< Whether the router says
 +                                           * it allows single hop exits. */
 +
    unsigned int wants_to_be_hs_dir:1; /**< True iff this router claims to be
                                        * a hidden service directory. */
 -  unsigned int is_hs_dir:1; /**< True iff this router is a hidden service
 -                             * directory according to the authorities. */
    unsigned int policy_is_reject_star:1; /**< True iff the exit policy for this
                                           * router rejects everything. */
    /** True if, after we have added this router, we should re-launch
     * tests for it. */
    unsigned int needs_retest_if_added:1;
  
 -/** Tor can use this router for general positions in circuits. */
 +/** Tor can use this router for general positions in circuits; we got it
 + * from a directory server as usual, or we're an authority and a server
 + * uploaded it. */
  #define ROUTER_PURPOSE_GENERAL 0
 -/** Tor should avoid using this router for circuit-building. */
 +/** Tor should avoid using this router for circuit-building: we got it
 + * from a crontroller.  If the controller wants to use it, it'll have to
 + * ask for it by identity. */
  #define ROUTER_PURPOSE_CONTROLLER 1
 -/** Tor should use this router only for bridge positions in circuits. */
 +/** Tor should use this router only for bridge positions in circuits: we got
 + * it via a directory request from the bridge itself, or a bridge
 + * authority. x*/
  #define ROUTER_PURPOSE_BRIDGE 2
  /** Tor should not use this router; it was marked in cached-descriptors with
   * a purpose we didn't recognize. */
  #define ROUTER_PURPOSE_UNKNOWN 255
  
 -  uint8_t purpose; /** What positions in a circuit is this router good for? */
 +  /* In what way did we find out about this router?  One of ROUTER_PURPOSE_*.
 +   * Routers of different purposes are kept segregated and used for different
 +   * things; see notes on ROUTER_PURPOSE_* macros above.
 +   */
 +  uint8_t purpose;
  
    /* The below items are used only by authdirservers for
     * reachability testing. */
 +
    /** When was the last time we could reach this OR? */
    time_t last_reachable;
    /** When did we start testing reachability for this OR? */
    time_t testing_since;
 -  /** According to the geoip db what country is this router in? */
 -  country_t country;
 +
  } routerinfo_t;
  
  /** Information needed to keep and cache a signed extra-info document. */
@@@ -1585,9 -1521,8 +1585,9 @@@ typedef struct routerstatus_t 
                                        * has. */
    char identity_digest[DIGEST_LEN]; /**< Digest of the router's identity
                                       * key. */
 -  char descriptor_digest[DIGEST_LEN]; /**< Digest of the router's most recent
 -                                       * descriptor. */
 +  /** Digest of the router's most recent descriptor or microdescriptor.
 +   * If it's a descriptor, we only use the first DIGEST_LEN bytes. */
 +  char descriptor_digest[DIGEST256_LEN];
    uint32_t addr; /**< IPv4 address for this router. */
    uint16_t or_port; /**< OR port for this router. */
    uint16_t dir_port; /**< Directory port for this router. */
@@@ -1595,11 -1530,7 +1595,11 @@@
    unsigned int is_exit:1; /**< True iff this router is a good exit. */
    unsigned int is_stable:1; /**< True iff this router stays up a long time. */
    unsigned int is_fast:1; /**< True iff this router has good bandwidth. */
 -  unsigned int is_running:1; /**< True iff this router is up. */
 +  /** True iff this router is called 'running' in the consensus. We give it
 +   * this funny name so that we don't accidentally use this bit as a view of
 +   * whether we think the router is *currently* running.  If that's what you
 +   * want to know, look at is_running in node_t. */
 +  unsigned int is_flagged_running:1;
    unsigned int is_named:1; /**< True iff "nickname" belongs to this router. */
    unsigned int is_unnamed:1; /**< True iff "nickname" belongs to another
                                * router. */
@@@ -1651,31 -1582,15 +1651,31 @@@
     * from this authority.)  Applies in v2 networkstatus document only.
     */
    unsigned int need_to_mirror:1;
 -  unsigned int name_lookup_warned:1; /**< Have we warned the user for referring
 -                                      * to this (unnamed) router by nickname?
 -                                      */
    time_t last_dir_503_at; /**< When did this router last tell us that it
                             * was too busy to serve directory info? */
    download_status_t dl_status;
  
  } routerstatus_t;
  
 +/** A single entry in a parsed policy summary, describing a range of ports. */
 +typedef struct short_policy_entry_t {
 +  uint16_t min_port, max_port;
 +} short_policy_entry_t;
 +
 +/** A short_poliy_t is the parsed version of a policy summary. */
 +typedef struct short_policy_t {
 +  /** True if the members of 'entries' are port ranges to accept; false if
 +   * they are port ranges to reject */
 +  unsigned int is_accept : 1;
 +  /** The actual number of values in 'entries'. */
 +  unsigned int n_entries : 31;
 +  /** An array of 0 or more short_policy_entry_t values, each describing a
 +   * range of ports that this policy accepts or rejects (depending on the
 +   * value of is_accept).
 +   */
 +  short_policy_entry_t entries[FLEXIBLE_ARRAY_MEMBER];
 +} short_policy_t;
 +
  /** A microdescriptor is the smallest amount of information needed to build a
   * circuit through a router.  They are generated by the directory authorities,
   * using information from the uploaded routerinfo documents.  They are not
@@@ -1717,83 -1632,15 +1717,83 @@@ typedef struct microdesc_t 
    crypto_pk_env_t *onion_pkey;
    /** As routerinfo_t.family */
    smartlist_t *family;
 -  /** Encoded exit policy summary */
 -  char *exitsummary; /**< exit policy summary -
 -                      * XXX this probably should not stay a string. */
 +  /** Exit policy summary */
 +  short_policy_t *exit_policy;
  } microdesc_t;
  
 +/** A node_t represents a Tor router.
 + *
 + * Specifically, a node_t is a Tor router as we are using it: a router that
 + * we are considering for circuits, connections, and so on.  A node_t is a
 + * thin wrapper around the routerstatus, routerinfo, and microdesc for a
 + * single wrapper, and provides a consistent interface for all of them.
 + *
 + * Also, a node_t has mutable state.  While a routerinfo, a routerstatus,
 + * and a microdesc have[*] only the information read from a router
 + * descriptor, a consensus entry, and a microdescriptor (respectively)...
 + * a node_t has flags based on *our own current opinion* of the node.
 + *
 + * [*] Actually, there is some leftover information in each that is mutable.
 + *  We should try to excise that.
 + */
 +typedef struct node_t {
 +  /* Indexing information */
 +
 +  /** Used to look up the node_t by its identity digest. */
 +  HT_ENTRY(node_t) ht_ent;
 +  /** Position of the node within the list of nodes */
 +  int nodelist_idx;
 +
 +  /** The identity digest of this node_t.  No more than one node_t per
 +   * identity may exist at a time. */
 +  char identity[DIGEST_LEN];
 +
 +  microdesc_t *md;
 +  routerinfo_t *ri;
 +  routerstatus_t *rs;
 +
 +  /* local info: copied from routerstatus, then possibly frobbed based
 +   * on experience.  Authorities set this stuff directly. */
 +
 +  unsigned int is_running:1; /**< As far as we know, is this OR currently
 +                              * running? */
 +  unsigned int is_valid:1; /**< Has a trusted dirserver validated this OR?
 +                               *  (For Authdir: Have we validated this OR?)
 +                               */
 +  unsigned int is_fast:1; /** Do we think this is a fast OR? */
 +  unsigned int is_stable:1; /** Do we think this is a stable OR? */
 +  unsigned int is_possible_guard:1; /**< Do we think this is an OK guard? */
 +  unsigned int is_exit:1; /**< Do we think this is an OK exit? */
 +  unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked,
 +                               * or otherwise nasty? */
 +  unsigned int is_bad_directory:1; /**< Do we think this directory is junky,
 +                                    * underpowered, or otherwise useless? */
 +  unsigned int is_hs_dir:1; /**< True iff this router is a hidden service
 +                             * directory according to the authorities. */
 +
 +  /* Local info: warning state. */
 +
 +  unsigned int name_lookup_warned:1; /**< Have we warned the user for referring
 +                                      * to this (unnamed) router by nickname?
 +                                      */
 +
 +  /** Local info: we treat this node as if it rejects everything */
 +  unsigned int rejects_all:1;
 +
 +  /* Local info: derived. */
 +
 +  /** According to the geoip db what country is this router in? */
 +  country_t country;
 +} node_t;
 +
  /** How many times will we try to download a router's descriptor before giving
   * up? */
  #define MAX_ROUTERDESC_DOWNLOAD_FAILURES 8
  
 +/** How many times will we try to download a microdescriptor before giving
 + * up? */
 +#define MAX_MICRODESC_DOWNLOAD_FAILURES 8
 +
  /** Contents of a v2 (non-consensus, non-vote) network status object. */
  typedef struct networkstatus_v2_t {
    /** When did we receive the network-status document? */
@@@ -2269,12 -2116,10 +2269,12 @@@ typedef struct circuit_t 
      * length ONIONSKIN_CHALLENGE_LEN. */
    char *n_conn_onionskin;
  
 -  time_t timestamp_created; /**< When was this circuit created? */
 +  /** When was this circuit created?  We keep this timestamp with a higher
 +   * resolution than most so that the circuit-build-time tracking code can
 +   * get millisecond resolution. */
 +  struct timeval timestamp_created;
    time_t timestamp_dirty; /**< When the circuit was first used, or 0 if the
                             * circuit is clean. */
 -  struct timeval highres_created; /**< When exactly was the circuit created? */
  
    uint16_t marked_for_close; /**< Should we close this circuit at the end of
                                * the main loop? (If true, holds the line number
@@@ -2499,7 -2344,6 +2499,7 @@@ typedef struct 
  
    config_line_t *Logs; /**< New-style list of configuration lines
                          * for logs */
 +  int LogTimeGranularity; /**< Log resolution in milliseconds. */
  
    int LogMessageDomains; /**< Boolean: Should we log the domain(s) in which
                            * each log message occurs? */
@@@ -2722,9 -2566,6 +2722,9 @@@
                                 * authorizations for hidden services */
    char *ContactInfo; /**< Contact info to be published in the directory. */
  
 +  int HeartbeatPeriod; /**< Log heartbeat messages after this many seconds
 +                        * have passed. */
 +
    char *HTTPProxy; /**< hostname[:port] to use as http proxy, if any. */
    tor_addr_t HTTPProxyAddr; /**< Parsed IPv4 addr for http proxy, if any. */
    uint16_t HTTPProxyPort; /**< Parsed port for http proxy, if any. */
@@@ -2762,8 -2603,7 +2762,8 @@@
  
    char *MyFamily; /**< Declared family for this OR. */
    config_line_t *NodeFamilies; /**< List of config lines for
 -                                       * node families */
 +                                * node families */
 +  smartlist_t *NodeFamilySets; /**< List of parsed NodeFamilies values. */
    config_line_t *AuthDirBadDir; /**< Address policy for descriptors to
                                   * mark as bad dir mirrors. */
    config_line_t *AuthDirBadExit; /**< Address policy for descriptors to
@@@ -2868,10 -2708,6 +2868,10 @@@
                         * possible. */
    int PreferTunneledDirConns; /**< If true, avoid dirservers that don't
                                 * support BEGIN_DIR, when possible. */
 +  int PortForwarding; /**< If true, use NAT-PMP or UPnP to automatically
 +                       * forward the DirPort and ORPort on the NAT device */
 +  char *PortForwardingHelper; /** < Filename or full path of the port
 +                                  forwarding helper executable */
    int AllowNonRFC953Hostnames; /**< If true, we allow connections to hostnames
                                  * with weird characters. */
    /** If true, we try resolving hostnames with weird characters. */
@@@ -2909,9 -2745,6 +2909,9 @@@
    /** If true, the user wants us to collect statistics on port usage. */
    int ExitPortStatistics;
  
 +  /** If true, the user wants us to collect connection statistics. */
 +  int ConnDirectionStatistics;
 +
    /** If true, the user wants us to collect cell statistics. */
    int CellStatistics;
  
@@@ -3008,12 -2841,11 +3008,17 @@@
     */
    double CircuitPriorityHalflife;
  
 +  /** If true, do not enable IOCP on windows with bufferevents, even if
 +   * we think we could. */
 +  int DisableIOCP;
 +  /** For testing only: will go away in 0.2.3.x. */
 +  int _UseFilteringSSLBufferevents;
 +
+   /** Set to true if the TestingTorNetwork configuration option is set.
+    * This is used so that options_validate() has a chance to realize that
+    * the defaults have changed. */
+   int _UsingTestNetworkDefaults;
+ 
  } or_options_t;
  
  /** Persistent state for an onion router, as saved to disk. */
@@@ -3128,6 -2960,8 +3133,6 @@@ struct socks_request_t 
                                * every connection. */
  };
  
 -/* all the function prototypes go here */
 -
  /********************************* circuitbuild.c **********************/
  
  /** How many hops does a general-purpose circuit have by default? */
@@@ -3519,7 -3353,7 +3524,7 @@@ typedef enum 
    ADDR_POLICY_PROBABLY_ACCEPTED=1,
    /** Part of the address was unknown, but as far as we can tell, it was
     * rejected. */
 -  ADDR_POLICY_PROBABLY_REJECTED=2
 +  ADDR_POLICY_PROBABLY_REJECTED=2,
  } addr_policy_result_t;
  
  /********************************* rephist.c ***************************/
@@@ -3650,8 -3484,6 +3655,8 @@@ typedef struct trusted_dir_server_t 
   *  fetches to _any_ single directory server.]
   */
  #define PDS_NO_EXISTING_SERVERDESC_FETCH (1<<3)
 +#define PDS_NO_EXISTING_MICRODESC_FETCH (1<<4)
 +
  #define _PDS_PREFER_TUNNELED_DIR_CONNS (1<<16)
  
  /** Possible ways to weight routers when choosing one randomly.  See
@@@ -3669,8 -3501,7 +3674,8 @@@ typedef enum 
    CRN_NEED_GUARD = 1<<2,
    CRN_ALLOW_INVALID = 1<<3,
    /* XXXX not used, apparently. */
 -  CRN_WEIGHT_AS_EXIT = 1<<5
 +  CRN_WEIGHT_AS_EXIT = 1<<5,
 +  CRN_NEED_DESC = 1<<6
  } router_crn_flags_t;
  
  /** Return value for router_add_to_routerlist() and dirserv_add_descriptor() */



More information about the tor-commits mailing list