diff --git a/changes/ticket40337 b/changes/ticket40337 new file mode 100644 index 0000000000..1c86fc4c99 --- /dev/null +++ b/changes/ticket40337 @@ -0,0 +1,16 @@ + o Minor features (testing): + - On a testing network, relays can now use the + TestingMinTimeToReportBandwidth 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. + - Relays on testing networks no longer rate-limit how frequently + they are willing to report new bandwidth measurements. Part of a fix + for ticket 40337. diff --git a/doc/man/tor.1.txt b/doc/man/tor.1.txt index 7222cd0548..89afe59582 100644 --- a/doc/man/tor.1.txt +++ b/doc/man/tor.1.txt @@ -3597,6 +3597,11 @@ The following options are used for running a testing Tor network. Minimum value for the Fast flag. Overrides the ordinary minimum taken from the consensus when TestingTorNetwork is set. (Default: 0.) +[[TestingMinTimeToReportBandwidth]] **TestingMinTimeToReportBandwidth** __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. + Values over 1 day have no effect. (Default: 1 day) + [[TestingServerConsensusDownloadInitialDelay]] **TestingServerConsensusDownloadInitialDelay** __N__:: Initial delay in seconds for when servers should download consensuses. Changing this requires that **TestingTorNetwork** is set. (Default: 0) diff --git a/src/app/config/config.c b/src/app/config/config.c index bfa258c904..2877bc1e6a 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -550,6 +550,7 @@ static const config_var_t option_vars_[] = { V(MaxUnparseableDescSizeToLog, MEMUNIT, "10 MB"), VPORT(MetricsPort), V(MetricsPortPolicy, LINELIST, NULL), + V(TestingMinTimeToReportBandwidth, INTERVAL, "1 day"), VAR("MyFamily", LINELIST, MyFamily_lines, NULL), V(NewCircuitPeriod, INTERVAL, "30 seconds"), OBSOLETE("NamingAuthoritativeDirectory"), @@ -3980,6 +3981,7 @@ options_validate_cb(const void *old_options_, void *options_, char **msg) CHECK_DEFAULT(TestingSigningKeySlop); CHECK_DEFAULT(TestingAuthKeySlop); CHECK_DEFAULT(TestingLinkKeySlop); + CHECK_DEFAULT(TestingMinTimeToReportBandwidth); or_options_free(dflt_options); } #undef CHECK_DEFAULT diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h index 510ece42a3..151b77c457 100644 --- a/src/app/config/or_options_st.h +++ b/src/app/config/or_options_st.h @@ -1060,6 +1060,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 TestingMinTimeToReportBandwidth; + /** * Configuration objects for individual modules. * diff --git a/src/app/config/testnet.inc b/src/app/config/testnet.inc index 00b307782b..039454a0d0 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" }, +{ "TestingMinTimeToReportBandwidth", "0 seconds" }, { "TestingServerDownloadInitialDelay", "0" }, { "TestingClientDownloadInitialDelay", "0" }, { "TestingServerConsensusDownloadInitialDelay", "0" }, diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 67d3e3ee75..a2ca472307 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -2622,7 +2622,10 @@ check_descriptor_bandwidth_changed(time_t now) if ((prev != cur && (!prev || !cur)) || cur > (prev * BANDWIDTH_CHANGE_FACTOR) || cur < (prev / BANDWIDTH_CHANGE_FACTOR) ) { - if (last_changed+MAX_BANDWIDTH_CHANGE_FREQ < now || !prev) { + const bool change_recent_enough = + last_changed+MAX_BANDWIDTH_CHANGE_FREQ < now; + const bool testing_network = get_options()->TestingTorNetwork; + if (change_recent_enough || testing_network || !prev) { log_info(LD_GENERAL, "Measured bandwidth has changed; rebuilding descriptor."); mark_my_descriptor_dirty("bandwidth has changed"); diff --git a/src/feature/stats/bwhist.c b/src/feature/stats/bwhist.c index d5a9b73605..552dc7ad74 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; imaxima[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()->TestingMinTimeToReportBandwidth; + 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 e7fc60fdee..d61c442e5d 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 7338340e25..dbedc021e4 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));