diff --git a/changes/bug1789 b/changes/bug1789 new file mode 100644 index 0000000000..1f9e6b15b2 --- /dev/null +++ b/changes/bug1789 @@ -0,0 +1,8 @@ + o Minor features: + - Be more generous with how much bandwidth we'd use up (with + accounting enabled) before entering "soft hibernation". + Previously, we'd hibernate once we'd used up 95% of our allotment. + Now, we use up 95% of our allotment, AND make sure that we have + no more than 500MB/3 hours of traffic remaining before we enter + soft hibernation. + diff --git a/src/or/hibernate.c b/src/or/hibernate.c index 30f1ad224f..351da93cd7 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -637,8 +637,27 @@ hibernate_hard_limit_reached(void) static int hibernate_soft_limit_reached(void) { - uint64_t soft_limit = DBL_TO_U64(U64_TO_DBL(get_options()->AccountingMax) - * .95); + const uint64_t acct_max = get_options()->AccountingMax; +#define SOFT_LIM_PCT (.95) +#define SOFT_LIM_BYTES (500*1024*1024) +#define SOFT_LIM_MINUTES (3*60) + /* The 'soft limit' is a fair bit more complicated now than once it was. + * We want to stop accepting connections when ALL of the following are true: + * - We expect to use up the remaining bytes in under 3 hours + * - We have used up 95% of our bytes. + * - We have less than 500MB of bytes left. + */ + uint64_t soft_limit = DBL_TO_U64(U64_TO_DBL(acct_max) * SOFT_LIM_PCT); + if (acct_max > SOFT_LIM_BYTES && acct_max - SOFT_LIM_BYTES > soft_limit) { + soft_limit = acct_max - SOFT_LIM_BYTES; + } + if (expected_bandwidth_usage) { + const uint64_t expected_usage = + expected_bandwidth_usage * SOFT_LIM_MINUTES; + if (acct_max > expected_usage && acct_max - expected_usage > soft_limit) + soft_limit = acct_max - expected_usage; + } + if (!soft_limit) return 0; return n_bytes_read_in_interval >= soft_limit