[or-cvs] Add "MEMUNIT" and "INTERVAL" types to configuration. Also t...

Nick Mathewson nickm at seul.org
Sat Nov 20 00:37:03 UTC 2004


Update of /home/or/cvsroot/tor/src/or
In directory moria.mit.edu:/tmp/cvs-serv12455/src/or

Modified Files:
	config.c connection.c connection_or.c hibernate.c or.h 
	router.c 
Log Message:
Add "MEMUNIT" and "INTERVAL" types to configuration. Also tweak Accounting setup.  More docs needed

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/config.c,v
retrieving revision 1.257
retrieving revision 1.258
diff -u -d -r1.257 -r1.258
--- config.c	15 Nov 2004 09:05:54 -0000	1.257
+++ config.c	20 Nov 2004 00:37:00 -0000	1.258
@@ -20,6 +20,10 @@
 typedef enum config_type_t {
   CONFIG_TYPE_STRING = 0,   /**< An arbitrary string. */
   CONFIG_TYPE_UINT,         /**< A non-negative integer less than MAX_INT */
+  /* DOCDOC */
+  CONFIG_TYPE_INTERVAL,     /**< A non-negative integer less than MAX_INT */
+  /* DOCDOC */
+  CONFIG_TYPE_MEMUNIT,       /**< A non-negative integer less than MAX_INT */
   CONFIG_TYPE_DOUBLE,       /**< A floating-point value */
   CONFIG_TYPE_BOOL,         /**< A boolean value, expressed as 0 or 1. */
   CONFIG_TYPE_CSV,          /**< A list of strings, separated by commas and optional
@@ -55,8 +59,8 @@
   PLURAL(RendNode),
   PLURAL(RendExcludeNode),
   { "l", "Log", 1},
-  { "BandwidthRate", "BandwidthRateBytes", 0},
-  { "BandwidthBurst", "BandwidthBurstBytes", 0},
+  { "BandwidthRateBytes", "BandwidthRate", 0},
+  { "BandwidthBurstBytes", "BandwidthBurst", 0},
   { "DirFetchPostPeriod", "DirFetchPeriod", 0},
   { NULL, NULL , 0},
 };
@@ -89,8 +93,8 @@
   VAR("Address",             STRING,   Address,              NULL),
   VAR("AllowUnverifiedNodes",CSV,      AllowUnverifiedNodes, "middle,rendezvous"),
   VAR("AuthoritativeDirectory",BOOL,   AuthoritativeDir,     "0"),
-  VAR("BandwidthRateBytes",  UINT,     BandwidthRateBytes,   "800000"),
-  VAR("BandwidthBurstBytes", UINT,     BandwidthBurstBytes,  "50000000"),
+  VAR("BandwidthRate",       MEMUNIT,   BandwidthRate,   "780 KB"),
+  VAR("BandwidthBurst",      MEMUNIT,   BandwidthBurst,  "48 MB"),
   VAR("ClientOnly",          BOOL,     ClientOnly,           "0"),
   VAR("ContactInfo",         STRING,   ContactInfo,          NULL),
   VAR("ControlPort",         UINT,     ControlPort,          "0"),
@@ -99,9 +103,9 @@
   VAR("DataDirectory",       STRING,   DataDirectory,        NULL),
   VAR("DirPort",             UINT,     DirPort,              "0"),
   VAR("DirBindAddress",      LINELIST, DirBindAddress,       NULL),
-  VAR("DirFetchPeriod",      UINT,     DirFetchPeriod,       "3600"),
-  VAR("DirPostPeriod",       UINT,     DirPostPeriod,        "600"),
-  VAR("RendPostPeriod",      UINT,     RendPostPeriod,       "600"),
+  VAR("DirFetchPeriod",      INTERVAL, DirFetchPeriod,       "1 hour"),
+  VAR("DirPostPeriod",       INTERVAL, DirPostPeriod,        "10 mintues"),
+  VAR("RendPostPeriod",      INTERVAL, RendPostPeriod,       "10 minutes"),
   VAR("DirPolicy",           LINELIST, DirPolicy,            NULL),
   VAR("DirServer",           LINELIST, DirServers,           NULL),
   VAR("ExitNodes",           STRING,   ExitNodes,            NULL),
@@ -123,7 +127,7 @@
   VAR("HiddenServiceNodes",  LINELIST_S, RendConfigLines,    NULL),
   VAR("HiddenServiceExcludeNodes", LINELIST_S, RendConfigLines, NULL),
   VAR("IgnoreVersion",       BOOL,     IgnoreVersion,        "0"),
-  VAR("KeepalivePeriod",     UINT,     KeepalivePeriod,      "300"),
+  VAR("KeepalivePeriod",     INTERVAL, KeepalivePeriod,      "5 minutes"),
   VAR("Log",                 LINELIST, Logs,                 NULL),
   VAR("LogLevel",            LINELIST_S, OldLogOptions,      NULL),
   VAR("LogFile",             LINELIST_S, OldLogOptions,      NULL),
@@ -131,9 +135,10 @@
   VAR("MaxConn",             UINT,     MaxConn,              "1024"),
   VAR("MaxOnionsPending",    UINT,     MaxOnionsPending,     "100"),
   VAR("MonthlyAccountingStart",UINT,   AccountingStart,      "1"),
-  VAR("AccountingMaxKB",     UINT,     AccountingMaxKB,      "0"),
+  VAR("AccountingMaxKB",     UINT,     _AccountingMaxKB,     "0"),
+  VAR("AccountingMax",       MEMUNIT,   AccountingMax,        "0 bytes"),
   VAR("Nickname",            STRING,   Nickname,             NULL),
-  VAR("NewCircuitPeriod",    UINT,     NewCircuitPeriod,     "30"),
+  VAR("NewCircuitPeriod",    INTERVAL, NewCircuitPeriod,     "30 seconds"),
   VAR("NumCpus",             UINT,     NumCpus,              "1"),
   VAR("ORPort",              UINT,     ORPort,               "0"),
   VAR("ORBindAddress",       LINELIST, ORBindAddress,        NULL),
@@ -150,7 +155,7 @@
   VAR("SocksPort",           UINT,     SocksPort,            "9050"),
   VAR("SocksBindAddress",    LINELIST, SocksBindAddress,     NULL),
   VAR("SocksPolicy",         LINELIST, SocksPolicy,          NULL),
-  VAR("StatusFetchPeriod",   UINT,     StatusFetchPeriod,    "1200"),
+  VAR("StatusFetchPeriod",   INTERVAL, StatusFetchPeriod,    "20 minutes"),
   VAR("SysLog",              LINELIST_S, OldLogOptions,      NULL),
   OBSOLETE("TrafficShaping"),
   VAR("User",                STRING,   User,                 NULL),
@@ -185,6 +190,9 @@
 static int validate_data_directory(or_options_t *options);
 static int write_configuration_file(const char *fname, or_options_t *options);
 
+static uint64_t config_parse_memunit(const char *s, int *ok);
+static int config_parse_interval(const char *s, int *ok);
+
 /*
  * Functions to read and write the global options pointer.
  */
@@ -529,6 +537,24 @@
     *(int *)lvalue = i;
     break;
 
+  case CONFIG_TYPE_INTERVAL: {
+    i = config_parse_interval(c->value, &ok);
+    if (!ok) {
+      return -2;
+    }
+    *(int *)lvalue = i;
+    break;
+  }
+
+  case CONFIG_TYPE_MEMUNIT: {
+    uint64_t u64 = config_parse_memunit(c->value, &ok);
+    if (!ok) {
+      return -2;
+    }
+    *(uint64_t *)lvalue = u64;
+    break;
+  }
+
   case CONFIG_TYPE_BOOL:
     i = tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
     if (!ok) {
@@ -648,12 +674,18 @@
         return NULL;
       }
       break;
+    case CONFIG_TYPE_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. */
       tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
       result->value = tor_strdup(buf);
       break;
+    case CONFIG_TYPE_MEMUNIT:
+      tor_snprintf(buf, sizeof(buf), U64_FORMAT,
+                   U64_PRINTF_ARG(*(uint64_t*)value));
+      result->value = tor_strdup(buf);
+      break;
     case CONFIG_TYPE_DOUBLE:
       tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
       result->value = tor_strdup(buf);
@@ -771,10 +803,14 @@
     case CONFIG_TYPE_DOUBLE:
       *(double*)lvalue = 0.0;
       break;
+    case CONFIG_TYPE_INTERVAL:
     case CONFIG_TYPE_UINT:
     case CONFIG_TYPE_BOOL:
       *(int*)lvalue = 0;
       break;
+    case CONFIG_TYPE_MEMUNIT:
+      *(uint64_t*)lvalue = 0;
+      break;
     case CONFIG_TYPE_CSV:
       if (*(smartlist_t**)lvalue) {
         SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
@@ -930,6 +966,8 @@
   for (i=0; config_vars[i].name; ++i) {
     lvalue = ((char*)options) + config_vars[i].var_offset;
     switch(config_vars[i].type) {
+      case CONFIG_TYPE_MEMUNIT:
+      case CONFIG_TYPE_INTERVAL:
       case CONFIG_TYPE_UINT:
       case CONFIG_TYPE_BOOL:
       case CONFIG_TYPE_DOUBLE:
@@ -1183,6 +1221,12 @@
     result = -1;
   }
 
+  if (options->_AccountingMaxKB) {
+    log(LOG_WARN, "AccountingMaxKB is deprecated.  Say 'AccountingMax %d KB' instead.", options->_AccountingMaxKB);
+    options->AccountingMax = U64_LITERAL(1024)*options->_AccountingMaxKB;
+    options->_AccountingMaxKB = 0;
+  }
+
   if (options->FirewallPorts) {
     SMARTLIST_FOREACH(options->FirewallPorts, const char *, cp,
     {
@@ -1257,8 +1301,8 @@
     result = -1;
   }
 
-  if (2*options->BandwidthRateBytes >= options->BandwidthBurstBytes) {
-    log(LOG_WARN,"BandwidthBurstBytes must be more than twice BandwidthRateBytes.");
+  if (2*options->BandwidthRate >= options->BandwidthBurst) {
+    log(LOG_WARN,"BandwidthBurst must be more than twice BandwidthRate.");
     result = -1;
   }
 
@@ -2161,6 +2205,121 @@
   return write_configuration_file(fn, get_options());
 }
 
+struct unit_table_t {
+  const char *unit;
+  uint64_t multiplier;
+};
+
+static struct unit_table_t memory_units[] = {
+  { "byte",      1<< 0 },
+  { "bytes",     1<< 0 },
+  { "k",         1<<10 },
+  { "kb",        1<<10 },
+  { "kilobyte",  1<<10 },
+  { "kilobytes", 1<<10 },
+  { "m",         1<<20 },
+  { "mb",        1<<20 },
+  { "megabyte",  1<<20 },
+  { "megabytes", 1<<20 },
+  { "g",         1<<30 },
+  { "gb",        1<<30 },
+  { "gigabyte",  1<<30 },
+  { "gigabytes", 1<<30 },
+  { "t",         U64_LITERAL(1)<<40 },
+  { "tb",        U64_LITERAL(1)<<40 },
+  { "terabyte",  U64_LITERAL(1)<<40 },
+  { "terabytes", U64_LITERAL(1)<<40 },
+  { NULL, 0 },
+};
+
+static struct unit_table_t time_units[] = {
+  { "s",        1 },
+  { "sec",      1 },
+  { "secs",     1 },
+  { "second",   1 },
+  { "seconds",  1 },
+  { "min",      60 },
+  { "mins",     60 },
+  { "minute",   60 },
+  { "minutes",  60 },
+  { "h",        60*60 },
+  { "hr",       60*60 },
+  { "hrs",      60*60 },
+  { "hour",     60*60 },
+  { "hours",    60*60 },
+  { "day",      24*60*60 },
+  { "days",     24*60*60 },
+  { "week",     7*24*60*60 },
+  { "weeks",    7*24*60*60 },
+  { 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.
+ * On success, set *<b>ok</b> to 1 and return this product.
+ * Otherwise, set *<b>ok</b> to 0.
+ */
+static uint64_t
+config_parse_units(const char *val, struct unit_table_t *u, int *ok)
+{
+  uint64_t v;
+  char *cp;
+
+  tor_assert(ok);
+
+  v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
+  if (!*ok)
+    return 0;
+  if (!cp) {
+    *ok = 1;
+    return v;
+  }
+  while(isspace(*cp))
+    ++cp;
+  for ( ;u->unit;++u) {
+    if (!strcasecmp(u->unit, cp)) {
+      v *= u->multiplier;
+      *ok = 1;
+      return v;
+    }
+  }
+  log_fn(LOG_WARN, "Unknown unit '%s'.", cp);
+  *ok = 0;
+  return 0;
+}
+
+/** Parse a string in the format "number unit", where unit is a unit of
+ * information (byte, KB, M, etc).  On success, set *<b>ok</b> to true
+ * and return the number of bytes specified.  Otherwise, set
+ * *<b>ok</b> to false and return 0. */
+static uint64_t
+config_parse_memunit(const char *s, int *ok) {
+  return config_parse_units(s, memory_units, ok);
+}
+
+/** 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.
+ */
+static int
+config_parse_interval(const char *s, int *ok) {
+  uint64_t r;
+  r = config_parse_units(s, time_units, ok);
+  if (!ok)
+    return -1;
+  if (r > INT_MAX) {
+    log_fn(LOG_WARN, "Interval '%s' is too long", s);
+    *ok = 0;
+    return -1;
+  } else if (r<0) {
+    log_fn(LOG_WARN, "Interval '%s' is negative", s);
+    *ok = 0;
+    return -1;
+  }
+  return r;
+}
+
 /*
   Local Variables:
   mode:c

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.290
retrieving revision 1.291
diff -u -d -r1.290 -r1.291
--- connection.c	15 Nov 2004 07:50:15 -0000	1.290
+++ connection.c	20 Nov 2004 00:37:00 -0000	1.291
@@ -718,12 +718,12 @@
   }
 }
 
-/** Initiatialize the global read bucket to options->BandwidthBurstBytes,
+/** Initiatialize the global read bucket to options->BandwidthBurst,
  * and current_time to the current time. */
 void connection_bucket_init(void) {
   or_options_t *options = get_options();
-  global_read_bucket = options->BandwidthBurstBytes; /* start it at max traffic */
-  global_write_bucket = options->BandwidthBurstBytes; /* start it at max traffic */
+  global_read_bucket = options->BandwidthBurst; /* start it at max traffic */
+  global_write_bucket = options->BandwidthBurst; /* start it at max traffic */
 }
 
 /** A second has rolled over; increment buckets appropriately. */
@@ -734,12 +734,12 @@
   or_options_t *options = get_options();
 
   /* refill the global buckets */
-  if(global_read_bucket < options->BandwidthBurstBytes) {
-    global_read_bucket += options->BandwidthRateBytes;
+  if(global_read_bucket < options->BandwidthBurst) {
+    global_read_bucket += options->BandwidthRate;
     log_fn(LOG_DEBUG,"global_read_bucket now %d.", global_read_bucket);
   }
-  if(global_write_bucket < options->BandwidthBurstBytes) {
-    global_write_bucket += options->BandwidthRateBytes;
+  if(global_write_bucket < options->BandwidthBurst) {
+    global_write_bucket += options->BandwidthRate;
     log_fn(LOG_DEBUG,"global_write_bucket now %d.", global_write_bucket);
   }
 

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_or.c,v
retrieving revision 1.141
retrieving revision 1.142
diff -u -d -r1.141 -r1.142
--- connection_or.c	15 Nov 2004 04:28:24 -0000	1.141
+++ connection_or.c	20 Nov 2004 00:37:00 -0000	1.142
@@ -136,7 +136,7 @@
   conn->addr = addr;
   conn->port = port;
   /* This next part isn't really right, but it's good enough for now. */
-  conn->receiver_bucket = conn->bandwidth = options->BandwidthBurstBytes;
+  conn->receiver_bucket = conn->bandwidth = options->BandwidthBurst;
   memcpy(conn->identity_digest, id_digest, DIGEST_LEN);
   /* If we're an authoritative directory server, we may know a
    * nickname for this router. */

Index: hibernate.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/hibernate.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- hibernate.c	16 Nov 2004 03:32:01 -0000	1.22
+++ hibernate.c	20 Nov 2004 00:37:00 -0000	1.23
@@ -95,7 +95,7 @@
  * hibernate, return 1, else return 0.
  */
 int accounting_is_enabled(or_options_t *options) {
-  if (options->AccountingMaxKB)
+  if (options->AccountingMax)
     return 1;
   return 0;
 }
@@ -205,13 +205,13 @@
 update_expected_bandwidth(void)
 {
   uint64_t used;
-  uint32_t max_configured = (get_options()->BandwidthRateBytes * 60);
+  uint32_t max_configured = (get_options()->BandwidthRate * 60);
 
   if (n_seconds_active_in_interval < 1800) {
     /* If we haven't gotten enough data last interval, guess that
      * we'll be used at our maximum capacity.  This is unlikely to be
      * so, but it will give us an okay first estimate, and we'll stay
-     * up until we send MaxKB kilobytes.  Next interval, we'll choose
+     * up until we send Max ytes.  Next interval, we'll choose
      * our starting time based on how much we sent this interval.
      */
     expected_bandwidth_usage = max_configured;
@@ -302,7 +302,7 @@
 
   if (expected_bandwidth_usage)
     n_days_to_exhaust_bw =
-      (get_options()->AccountingMaxKB/expected_bandwidth_usage)/(24*60);
+      (get_options()->AccountingMax/expected_bandwidth_usage)/(24*60);
   else
     n_days_to_exhaust_bw = 1;
 
@@ -442,7 +442,7 @@
 static int
 hibernate_hard_limit_reached(void)
 {
-  uint64_t hard_limit = get_options()->AccountingMaxKB<<10;
+  uint64_t hard_limit = get_options()->AccountingMax;
   if (!hard_limit)
     return 0;
   return n_bytes_read_in_interval >= hard_limit
@@ -453,7 +453,7 @@
  * to send/receive this interval. */
 static int hibernate_soft_limit_reached(void)
 {
-  uint64_t soft_limit = (uint64_t) ((get_options()->AccountingMaxKB<<10) * .99);
+  uint64_t soft_limit = (uint64_t) ((get_options()->AccountingMax) * .99);
   if (!soft_limit)
     return 0;
   return n_bytes_read_in_interval >= soft_limit
@@ -582,7 +582,7 @@
  * to start/stop hibernating.
  */
 void consider_hibernation(time_t now) {
-  int accounting_enabled = get_options()->AccountingMaxKB != 0;
+  int accounting_enabled = get_options()->AccountingMax != 0;
   char buf[ISO_TIME_LEN+1];
 
   /* If we're in 'exiting' mode, then we just shut down after the interval

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.486
retrieving revision 1.487
diff -u -d -r1.486 -r1.487
--- or.h	15 Nov 2004 09:05:54 -0000	1.486
+++ or.h	20 Nov 2004 00:37:00 -0000	1.487
@@ -937,9 +937,9 @@
                          * them? */
   int NewCircuitPeriod; /**< How long do we use a circuit before building
                          * a new one? */
-  int BandwidthRateBytes; /**< How much bandwidth, on average, are we willing to
+  uint64_t BandwidthRate; /**< How much bandwidth, on average, are we willing to
                            * use in a second? */
-  int BandwidthBurstBytes; /**< How much bandwidth, at maximum, are we willing to
+  uint64_t BandwidthBurst; /**< How much bandwidth, at maximum, are we willing to
                             * use in a second? */
   int NumCpus; /**< How many CPUs should we try to use? */
   int RunTesting; /**< If true, create testing circuits to measure how well the
@@ -963,9 +963,13 @@
   int AccountingStart; /**< At what offset within the accounting interval
                         * do we begin measuring?  (Currently only day-of-month
                         * is supported.) */
-  int AccountingMaxKB; /**< How many KB do we allow per accounting
-                        * interval before hibernation?  0 for "never
-                        * hibernate." */
+  uint64_t AccountingMax; /**< How many bytes do we allow per accounting
+                           * interval before hibernation?  0 for "never
+                           * hibernate." */
+  int _AccountingMaxKB; /**< How many KB do we allow per accounting
+                         * interval before hibernation?  0 for "never
+                         * hibernate." */
+
   char *HashedControlPassword; /**< Base64-encoded hash of a password for
                                 * the control system. */
   int CookieAuthentication; /**< Boolean: do we enable cookie-based auth for

Index: router.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/router.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -d -r1.120 -r1.121
--- router.c	13 Nov 2004 16:53:48 -0000	1.120
+++ router.c	20 Nov 2004 00:37:00 -0000	1.121
@@ -550,8 +550,8 @@
   }
   get_platform_str(platform, sizeof(platform));
   ri->platform = tor_strdup(platform);
-  ri->bandwidthrate = options->BandwidthRateBytes;
-  ri->bandwidthburst = options->BandwidthBurstBytes;
+  ri->bandwidthrate = options->BandwidthRate;
+  ri->bandwidthburst = options->BandwidthBurst;
   ri->bandwidthcapacity = router_get_bandwidth_capacity();
   router_add_exit_policy_from_config(ri);
   if(desc_routerinfo) /* inherit values */



More information about the tor-commits mailing list