[tor-commits] [tor/main] Add a MinTimeToReportBandwidth option; make it 0 for testing networks.

nickm at torproject.org nickm at torproject.org
Mon Jun 14 17:10:31 UTC 2021


commit 2ae24d003d1d12e8e202748c4398d7438e4a65d9
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Mar 17 08:45:37 2021 -0400

    Add a MinTimeToReportBandwidth option; make it 0 for testing networks.
    
    This option changes the time for which a bandwidth measurement period
    must have been in progress before we include it when reporting our
    observed bandwidth in our descriptors.  Without this option, we only
    consider a time period towards our maximum if it has been running
    for a full day.  Obviously, that's unacceptable for testing
    networks, where we'd like to get results as soon as possible.
    
    For non-testing networks, I've put a (somewhat arbitrary) 2-hour
    minimum on the option, since there are traffic analysis concerns
    with immediate reporting here.
    
    Closes #40337.
---
 changes/ticket40337            | 12 ++++++++++++
 doc/man/tor.1.txt              |  7 +++++++
 src/app/config/config.c        |  8 ++++++++
 src/app/config/config.h        |  7 +++++++
 src/app/config/or_options_st.h |  4 ++++
 src/app/config/testnet.inc     |  1 +
 src/feature/stats/bwhist.c     | 19 ++++++++++++++-----
 src/feature/stats/bwhist.h     |  2 +-
 src/test/test_relay.c          |  4 ++--
 9 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/changes/ticket40337 b/changes/ticket40337
new file mode 100644
index 0000000000..f8f136a740
--- /dev/null
+++ b/changes/ticket40337
@@ -0,0 +1,12 @@
+  o Minor features (bandwidth reporting):
+    - Relays can now use the MinTimeToReportBandwidth option to change
+      the smallest amount of time over which they're willing to report
+      their observed maximum bandwidth.  Previously, this was fixed
+      at 1 day.  For safety, values under 2 hours are only supported on
+      testing networks. Part of a fix for ticket 40337.
+
+  o Minor features (testing):
+    - Relays on testing networks now report their observed bandwidths
+      immediately from startup.  Previously, they waited
+      until they had been running for a full day.   Closes ticket
+      40337.
diff --git a/doc/man/tor.1.txt b/doc/man/tor.1.txt
index b57c6ec70a..af4ee494ef 100644
--- a/doc/man/tor.1.txt
+++ b/doc/man/tor.1.txt
@@ -2448,6 +2448,13 @@ is non-zero):
     If we have more onionskins queued for processing than we can process in
     this amount of time, reject new ones. (Default: 1750 msec)
 
+[[MinTimeToReportBandwidth]] **MinTimeToReportBandwidth** __N__ **seconds**|**minutes**|**hours**::
+    Do not report our measurements for our maximum observed bandwidth for any
+    time period that has lasted for less than this amount of time.
+    Setting this option too low can enable traffic analysis, and is
+    not permitted except on testing networks.  Values over 1 day have
+    no effect. (Default: 1 day)
+
 [[MyFamily]] **MyFamily** __fingerprint__,__fingerprint__,...::
     Declare that this Tor relay is controlled or administered by a group or
     organization identical or similar to that of the other relays, defined by
diff --git a/src/app/config/config.c b/src/app/config/config.c
index fa74907b3d..9011f36735 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -563,6 +563,7 @@ static const config_var_t option_vars_[] = {
   V(MaxUnparseableDescSizeToLog, MEMUNIT, "10 MB"),
   VPORT(MetricsPort),
   V(MetricsPortPolicy,           LINELIST, NULL),
+  V(MinTimeToReportBandwidth,    INTERVAL, "1 day"),
   VAR("MyFamily",                LINELIST, MyFamily_lines,       NULL),
   V(NewCircuitPeriod,            INTERVAL, "30 seconds"),
   OBSOLETE("NamingAuthoritativeDirectory"),
@@ -3711,6 +3712,13 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
     options->HeartbeatPeriod = MIN_HEARTBEAT_PERIOD;
   }
 
+  if (options->MinTimeToReportBandwidth < MIN_MIN_TIME_TO_REPORT_BW &&
+      !options->TestingTorNetwork) {
+    log_warn(LD_CONFIG, "MinTimeToReportBandwidth is too short; "
+             "raising to %d seconds.", MIN_MIN_TIME_TO_REPORT_BW);
+    options->MinTimeToReportBandwidth = MIN_MIN_TIME_TO_REPORT_BW;
+  }
+
   if (options->KeepalivePeriod < 1)
     REJECT("KeepalivePeriod option must be positive.");
 
diff --git a/src/app/config/config.h b/src/app/config/config.h
index e95ef4a728..74e6942eb5 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -24,6 +24,13 @@
  * expose more information than we're comfortable with. */
 #define MIN_HEARTBEAT_PERIOD (30*60)
 
+/**
+ * Lowest allowable value for MinTimeToReportBandwidth on a non-testing
+ * network; if this is too low we might report detail that is too
+ * fine-grained.
+ **/
+#define MIN_MIN_TIME_TO_REPORT_BW (2*60*60)
+
 /** Maximum default value for MaxMemInQueues, in bytes. */
 #if SIZEOF_VOID_P >= 8
 #define MAX_DEFAULT_MEMORY_QUEUE_SIZE (UINT64_C(8) << 30)
diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h
index 4364f145ed..efecc85d66 100644
--- a/src/app/config/or_options_st.h
+++ b/src/app/config/or_options_st.h
@@ -1082,6 +1082,10 @@ struct or_options_t {
   /** List of policy allowed to query the Metrics port. */
   struct config_line_t *MetricsPortPolicy;
 
+  /** How far must we be into the current bandwidth-measurement period to
+   * report bandwidth observations from this period? */
+  int MinTimeToReportBandwidth;
+
   /**
    * Configuration objects for individual modules.
    *
diff --git a/src/app/config/testnet.inc b/src/app/config/testnet.inc
index 00b307782b..527e0d00b1 100644
--- a/src/app/config/testnet.inc
+++ b/src/app/config/testnet.inc
@@ -19,6 +19,7 @@
 { "TestingV3AuthInitialDistDelay", "20 seconds" },
 { "TestingAuthDirTimeToLearnReachability", "0 minutes" },
 { "MinUptimeHidServDirectoryV2", "0 minutes" },
+{ "MinTimeToReportBandwidth", "0 seconds" },
 { "TestingServerDownloadInitialDelay", "0" },
 { "TestingClientDownloadInitialDelay", "0" },
 { "TestingServerConsensusDownloadInitialDelay", "0" },
diff --git a/src/feature/stats/bwhist.c b/src/feature/stats/bwhist.c
index 7cbc5f60a6..55a8f7c747 100644
--- a/src/feature/stats/bwhist.c
+++ b/src/feature/stats/bwhist.c
@@ -206,16 +206,24 @@ bwhist_note_dir_bytes_read(uint64_t num_bytes, time_t when)
   add_obs(dir_read_array, when, num_bytes);
 }
 
-/** Helper: Return the largest value in b->maxima.  (This is equal to the
+/**
+ * Helper: Return the largest value in b->maxima.  (This is equal to the
  * most bandwidth used in any NUM_SECS_ROLLING_MEASURE period for the last
  * NUM_SECS_BW_SUM_IS_VALID seconds.)
+ *
+ * Also include the current period if we have been observing it for
+ * at least min_observation_time seconds.
  */
 STATIC uint64_t
-find_largest_max(bw_array_t *b)
+find_largest_max(bw_array_t *b, int min_observation_time)
 {
   int i;
   uint64_t max;
-  max=0;
+  time_t period_start = b->next_period - NUM_SECS_BW_SUM_INTERVAL;
+  if (b->cur_obs_time > period_start + min_observation_time)
+    max = b->max_total;
+  else
+    max = 0;
   for (i=0; i<NUM_TOTALS; ++i) {
     if (b->maxima[i]>max)
       max = b->maxima[i];
@@ -233,8 +241,9 @@ MOCK_IMPL(int,
 bwhist_bandwidth_assess,(void))
 {
   uint64_t w,r;
-  r = find_largest_max(read_array);
-  w = find_largest_max(write_array);
+  int min_obs_time = get_options()->MinTimeToReportBandwidth;
+  r = find_largest_max(read_array, min_obs_time);
+  w = find_largest_max(write_array, min_obs_time);
   if (r>w)
     return (int)(((double)w)/NUM_SECS_ROLLING_MEASURE);
   else
diff --git a/src/feature/stats/bwhist.h b/src/feature/stats/bwhist.h
index f88b951447..01055df720 100644
--- a/src/feature/stats/bwhist.h
+++ b/src/feature/stats/bwhist.h
@@ -28,7 +28,7 @@ int bwhist_load_state(struct or_state_t *state, char **err);
 
 #ifdef BWHIST_PRIVATE
 typedef struct bw_array_t bw_array_t;
-STATIC uint64_t find_largest_max(bw_array_t *b);
+STATIC uint64_t find_largest_max(bw_array_t *b, int min_observation_time);
 STATIC void commit_max(bw_array_t *b);
 STATIC void advance_obs(bw_array_t *b);
 STATIC bw_array_t *bw_array_new(void);
diff --git a/src/test/test_relay.c b/src/test/test_relay.c
index b287f0d38b..8ed29b6282 100644
--- a/src/test/test_relay.c
+++ b/src/test/test_relay.c
@@ -98,7 +98,7 @@ test_relay_close_circuit(void *arg)
   tt_int_op(new_count, OP_EQ, old_count + 1);
 
   /* Ensure our write totals are 0 */
-  tt_u64_op(find_largest_max(write_array), OP_EQ, 0);
+  tt_u64_op(find_largest_max(write_array, 86400), OP_EQ, 0);
 
   /* Mark the circuit for close */
   circuit_mark_for_close(TO_CIRCUIT(orcirc), 0);
@@ -107,7 +107,7 @@ test_relay_close_circuit(void *arg)
   advance_obs(write_array);
   commit_max(write_array);
   /* Check for two cells plus overhead */
-  tt_u64_op(find_largest_max(write_array), OP_EQ,
+  tt_u64_op(find_largest_max(write_array, 86400), OP_EQ,
                              2*(get_cell_network_size(nchan->wide_circ_ids)
                                 +TLS_PER_CELL_OVERHEAD));
 





More information about the tor-commits mailing list