|
@@ -410,6 +410,16 @@ configure_accounting(time_t now)
|
|
|
accounting_set_wakeup_time();
|
|
|
}
|
|
|
|
|
|
+/** Return the relevant number of bytes sent/received this interval
|
|
|
+ * based on the set AccountingRule */
|
|
|
+static uint64_t
|
|
|
+get_accounting_bytes(void)
|
|
|
+{
|
|
|
+ if (strcmp(get_options()->AccountingRule, "sum") == 0)
|
|
|
+ return n_bytes_read_in_interval+n_bytes_written_in_interval;
|
|
|
+ return MAX(n_bytes_read_in_interval, n_bytes_written_in_interval);
|
|
|
+}
|
|
|
+
|
|
|
/** Set expected_bandwidth_usage based on how much we sent/received
|
|
|
* per minute last interval (if we were up for at least 30 minutes),
|
|
|
* or based on our declared bandwidth otherwise. */
|
|
@@ -421,6 +431,11 @@ update_expected_bandwidth(void)
|
|
|
uint64_t max_configured = (options->RelayBandwidthRate > 0 ?
|
|
|
options->RelayBandwidthRate :
|
|
|
options->BandwidthRate) * 60;
|
|
|
+ /* max_configured is the larger of bytes read and bytes written
|
|
|
+ * If we are accounting based on sum, worst case is both are
|
|
|
+ * at max, doubling the expected sum of bandwidth */
|
|
|
+ if (strcmp(get_options()->AccountingRule, "sum") == 0)
|
|
|
+ max_configured *= 2;
|
|
|
|
|
|
#define MIN_TIME_FOR_MEASUREMENT (1800)
|
|
|
|
|
@@ -439,8 +454,7 @@ update_expected_bandwidth(void)
|
|
|
* doesn't know to store soft-limit info. Just take rate at which
|
|
|
* we were reading/writing in the last interval as our expected rate.
|
|
|
*/
|
|
|
- uint64_t used = MAX(n_bytes_written_in_interval,
|
|
|
- n_bytes_read_in_interval);
|
|
|
+ uint64_t used = get_accounting_bytes();
|
|
|
expected = used / (n_seconds_active_in_interval / 60);
|
|
|
} else {
|
|
|
/* If we haven't gotten enough data last interval, set 'expected'
|
|
@@ -715,8 +729,7 @@ hibernate_hard_limit_reached(void)
|
|
|
uint64_t hard_limit = get_options()->AccountingMax;
|
|
|
if (!hard_limit)
|
|
|
return 0;
|
|
|
- return n_bytes_read_in_interval >= hard_limit
|
|
|
- || n_bytes_written_in_interval >= hard_limit;
|
|
|
+ return get_accounting_bytes() >= hard_limit;
|
|
|
}
|
|
|
|
|
|
/** Return true iff we have sent/received almost all the bytes we are willing
|
|
@@ -747,8 +760,7 @@ hibernate_soft_limit_reached(void)
|
|
|
|
|
|
if (!soft_limit)
|
|
|
return 0;
|
|
|
- return n_bytes_read_in_interval >= soft_limit
|
|
|
- || n_bytes_written_in_interval >= soft_limit;
|
|
|
+ return get_accounting_bytes() >= soft_limit;
|
|
|
}
|
|
|
|
|
|
/** Called when we get a SIGINT, or when bandwidth soft limit is
|
|
@@ -772,8 +784,7 @@ hibernate_begin(hibernate_state_t new_state, time_t now)
|
|
|
hibernate_state == HIBERNATE_STATE_LIVE) {
|
|
|
soft_limit_hit_at = now;
|
|
|
n_seconds_to_hit_soft_limit = n_seconds_active_in_interval;
|
|
|
- n_bytes_at_soft_limit = MAX(n_bytes_read_in_interval,
|
|
|
- n_bytes_written_in_interval);
|
|
|
+ n_bytes_at_soft_limit = get_accounting_bytes();
|
|
|
}
|
|
|
|
|
|
/* close listeners. leave control listener(s). */
|
|
@@ -1003,13 +1014,22 @@ getinfo_helper_accounting(control_connection_t *conn,
|
|
|
U64_PRINTF_ARG(n_bytes_written_in_interval));
|
|
|
} else if (!strcmp(question, "accounting/bytes-left")) {
|
|
|
uint64_t limit = get_options()->AccountingMax;
|
|
|
- uint64_t read_left = 0, write_left = 0;
|
|
|
- if (n_bytes_read_in_interval < limit)
|
|
|
- read_left = limit - n_bytes_read_in_interval;
|
|
|
- if (n_bytes_written_in_interval < limit)
|
|
|
- write_left = limit - n_bytes_written_in_interval;
|
|
|
- tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
|
|
|
- U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(write_left));
|
|
|
+ if (strcmp(get_options()->AccountingRule, "sum") == 0) {
|
|
|
+ uint64_t total_left = 0;
|
|
|
+ uint64_t total_bytes = get_accounting_bytes();
|
|
|
+ if (total_bytes < limit)
|
|
|
+ total_left = limit - total_bytes;
|
|
|
+ tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
|
|
|
+ U64_PRINTF_ARG(total_left), U64_PRINTF_ARG(total_left));
|
|
|
+ } else {
|
|
|
+ uint64_t read_left = 0, write_left = 0;
|
|
|
+ if (n_bytes_read_in_interval < limit)
|
|
|
+ read_left = limit - n_bytes_read_in_interval;
|
|
|
+ if (n_bytes_written_in_interval < limit)
|
|
|
+ write_left = limit - n_bytes_written_in_interval;
|
|
|
+ tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
|
|
|
+ U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(write_left));
|
|
|
+ }
|
|
|
} else if (!strcmp(question, "accounting/interval-start")) {
|
|
|
*answer = tor_malloc(ISO_TIME_LEN+1);
|
|
|
format_iso_time(*answer, interval_start_time);
|