diff options
-rw-r--r-- | changes/bug2434 | 6 | ||||
-rw-r--r-- | src/or/hibernate.c | 18 | ||||
-rw-r--r-- | src/or/hibernate.h | 1 | ||||
-rw-r--r-- | src/or/router.c | 23 |
4 files changed, 39 insertions, 9 deletions
diff --git a/changes/bug2434 b/changes/bug2434 new file mode 100644 index 0000000000..5fd3d11155 --- /dev/null +++ b/changes/bug2434 @@ -0,0 +1,6 @@ + o Minor features: + - Don't disable the DirPort when we cannot exceed our AccountingMax + limit during this interval because the effective bandwidthrate is + low enough. This is useful in a situation where AccountMax is only + used as an additional safeguard or to provide statistics. + diff --git a/src/or/hibernate.c b/src/or/hibernate.c index ce64581d1c..803f7f5764 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -242,6 +242,14 @@ accounting_is_enabled(const or_options_t *options) return 0; } +/** If accounting is enabled, return how long (in seconds) this + * interval lasts. */ +int +accounting_get_interval_length(void) +{ + return (int)(interval_end_time - interval_start_time); +} + /** Called from main.c to tell us that <b>seconds</b> seconds have * passed, <b>n_read</b> bytes have been read, and <b>n_written</b> * bytes have been written. */ @@ -504,7 +512,6 @@ accounting_set_wakeup_time(void) { char digest[DIGEST_LEN]; crypto_digest_env_t *d_env; - int time_in_interval; uint64_t time_to_exhaust_bw; int time_to_consider; @@ -538,22 +545,21 @@ accounting_set_wakeup_time(void) interval_wakeup_time = interval_start_time; log_notice(LD_ACCT, - "Configured hibernation. This interval begins at %s " - "and ends at %s. We have no prior estimate for bandwidth, so " + "Configured hibernation. This interval begins at %s " + "and ends at %s. We have no prior estimate for bandwidth, so " "we will start out awake and hibernate when we exhaust our quota.", buf1, buf2); return; } - time_in_interval = (int)(interval_end_time - interval_start_time); - time_to_exhaust_bw = (get_options()->AccountingMax/expected_bandwidth_usage)*60; if (time_to_exhaust_bw > INT_MAX) { time_to_exhaust_bw = INT_MAX; time_to_consider = 0; } else { - time_to_consider = time_in_interval - (int)time_to_exhaust_bw; + time_to_consider = accounting_get_interval_length() - + (int)time_to_exhaust_bw; } if (time_to_consider<=0) { diff --git a/src/or/hibernate.h b/src/or/hibernate.h index 78e7bb75e9..d77e946d4f 100644 --- a/src/or/hibernate.h +++ b/src/or/hibernate.h @@ -14,6 +14,7 @@ int accounting_parse_options(const or_options_t *options, int validate_only); int accounting_is_enabled(const or_options_t *options); +int accounting_get_interval_length(void); void configure_accounting(time_t now); void accounting_run_housekeeping(time_t now); void accounting_add_bytes(size_t n_read, size_t n_written, int seconds); diff --git a/src/or/router.c b/src/or/router.c index a08a2009a7..b2df3834fe 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -823,9 +823,26 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port) * make us choose not to publish. */ if (accounting_is_enabled(options)) { - /* if we might potentially hibernate */ - new_choice = 0; - reason = "AccountingMax enabled"; + /* Don't spend bytes for directory traffic if we could end up hibernating, + * but allow DirPort otherwise. Some people set AccountingMax because + * they're confused or to get statistics. */ + int interval_length = accounting_get_interval_length(); + uint32_t effective_bw = get_effective_bwrate(options); + if (!interval_length) { + log_warn(LD_BUG, "An accounting interval is not allowed to be zero " + "seconds long. Raising to 1."); + interval_length = 1; + } + log_info(LD_GENERAL, "Calculating whether to disable dirport: effective " + "bwrate: %u, AccountingMax: "U64_FORMAT", " + "accounting interval length %d", effective_bw, + U64_PRINTF_ARG(options->AccountingMax), + interval_length); + if (effective_bw >= + options->AccountingMax / interval_length) { + new_choice = 0; + reason = "AccountingMax enabled"; + } #define MIN_BW_TO_ADVERTISE_DIRPORT 51200 } else if (options->BandwidthRate < MIN_BW_TO_ADVERTISE_DIRPORT || (options->RelayBandwidthRate > 0 && |