mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Merge branch 'unixninja_ticket15989_squashed'
This commit is contained in:
commit
95f5910810
9
changes/ticket15989
Normal file
9
changes/ticket15989
Normal file
@ -0,0 +1,9 @@
|
||||
o Minor enhancement (accounting):
|
||||
- Added two modes to AccountingRule in torrc for
|
||||
limiting just input or just output.
|
||||
Closes ticket 15989; patch from "unixninja92".
|
||||
|
||||
o Minor bugfixe (accounting):
|
||||
- The max bandwidth when using AccountRule sum
|
||||
is now correctly logged.
|
||||
Patch from "unixninja92".
|
@ -1773,12 +1773,14 @@ is non-zero):
|
||||
of the time, which is more useful than a set of slow servers that are
|
||||
always "available".
|
||||
|
||||
[[AccountingRule]] **AccountingRule** **sum**|**max**::
|
||||
[[AccountingRule]] **AccountingRule** **sum**|**max**|**in**|**out**::
|
||||
How we determine when our AccountingMax has been reached (when we
|
||||
should hibernate) during a time interval. Set to "max" to calculate
|
||||
using the higher of either the sent or received bytes (this is the
|
||||
default functionality). Set to "sum" to calculate using the sent
|
||||
plus received bytes. (Default: max)
|
||||
plus received bytes. Set to "in" to calculate using only the
|
||||
received bytes. Set to "out" to calculate using only the sent bytes.
|
||||
(Default: max)
|
||||
|
||||
[[AccountingStart]] **AccountingStart** **day**|**week**|**month** [__day__] __HH:MM__::
|
||||
Specify how long accounting periods last. If **month** is given, each
|
||||
|
@ -3458,8 +3458,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
options->AccountingRule = ACCT_SUM;
|
||||
else if (!strcmp(options->AccountingRule_option, "max"))
|
||||
options->AccountingRule = ACCT_MAX;
|
||||
else if (!strcmp(options->AccountingRule_option, "in"))
|
||||
options->AccountingRule = ACCT_IN;
|
||||
else if (!strcmp(options->AccountingRule_option, "out"))
|
||||
options->AccountingRule = ACCT_OUT;
|
||||
else
|
||||
REJECT("AccountingRule must be 'sum' or 'max'");
|
||||
REJECT("AccountingRule must be 'sum', 'max', 'in', or 'out'");
|
||||
}
|
||||
|
||||
if (options->DirPort_set && !options->DirCache) {
|
||||
|
@ -412,11 +412,15 @@ configure_accounting(time_t now)
|
||||
|
||||
/** Return the relevant number of bytes sent/received this interval
|
||||
* based on the set AccountingRule */
|
||||
static uint64_t
|
||||
uint64_t
|
||||
get_accounting_bytes(void)
|
||||
{
|
||||
if (get_options()->AccountingRule == ACCT_SUM)
|
||||
return n_bytes_read_in_interval+n_bytes_written_in_interval;
|
||||
else if (get_options()->AccountingRule == ACCT_IN)
|
||||
return n_bytes_read_in_interval;
|
||||
else if (get_options()->AccountingRule == ACCT_OUT)
|
||||
return n_bytes_written_in_interval;
|
||||
else
|
||||
return MAX(n_bytes_read_in_interval, n_bytes_written_in_interval);
|
||||
}
|
||||
@ -1022,6 +1026,18 @@ getinfo_helper_accounting(control_connection_t *conn,
|
||||
total_left = limit - total_bytes;
|
||||
tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
|
||||
U64_PRINTF_ARG(total_left), U64_PRINTF_ARG(total_left));
|
||||
} else if (get_options()->AccountingRule == ACCT_IN) {
|
||||
uint64_t read_left = 0;
|
||||
if (n_bytes_read_in_interval < limit)
|
||||
read_left = limit - n_bytes_read_in_interval;
|
||||
tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
|
||||
U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(limit));
|
||||
} else if (get_options()->AccountingRule == ACCT_OUT) {
|
||||
uint64_t write_left = 0;
|
||||
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(limit), U64_PRINTF_ARG(write_left));
|
||||
} else {
|
||||
uint64_t read_left = 0, write_left = 0;
|
||||
if (n_bytes_read_in_interval < limit)
|
||||
|
@ -19,6 +19,7 @@ MOCK_DECL(int, accounting_is_enabled, (const or_options_t *options));
|
||||
int accounting_get_interval_length(void);
|
||||
MOCK_DECL(time_t, accounting_get_end_time, (void));
|
||||
void configure_accounting(time_t now);
|
||||
uint64_t get_accounting_bytes(void);
|
||||
void accounting_run_housekeeping(time_t now);
|
||||
void accounting_add_bytes(size_t n_read, size_t n_written, int seconds);
|
||||
int accounting_record_bandwidth_usage(time_t now, or_state_t *state);
|
||||
|
@ -3893,9 +3893,11 @@ typedef struct {
|
||||
* hibernate." */
|
||||
/** How do we determine when our AccountingMax has been reached?
|
||||
* "max" for when in or out reaches AccountingMax
|
||||
* "sum" for when in plus out reaches AccountingMax */
|
||||
* "sum" for when in plus out reaches AccountingMax
|
||||
* "in" for when in reaches AccountingMax
|
||||
* "out" for when out reaches AccountingMax */
|
||||
char *AccountingRule_option;
|
||||
enum { ACCT_MAX, ACCT_SUM } AccountingRule;
|
||||
enum { ACCT_MAX, ACCT_SUM, ACCT_IN, ACCT_OUT } AccountingRule;
|
||||
|
||||
/** Base64-encoded hash of accepted passwords for the control system. */
|
||||
config_line_t *HashedControlPassword;
|
||||
|
@ -1133,10 +1133,13 @@ router_should_be_directory_server(const or_options_t *options, int dir_port)
|
||||
int new_choice=1;
|
||||
const char *reason = NULL;
|
||||
|
||||
if (accounting_is_enabled(options)) {
|
||||
if (accounting_is_enabled(options) &&
|
||||
get_options()->AccountingRule != ACCT_IN) {
|
||||
/* 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. */
|
||||
* they're confused or to get statistics. Directory traffic has a much
|
||||
* larger effect on output than input so there is no reason to turn it
|
||||
* off if using AccountingRule in. */
|
||||
int interval_length = accounting_get_interval_length();
|
||||
uint32_t effective_bw = get_effective_bwrate(options);
|
||||
uint64_t acc_bytes;
|
||||
|
@ -164,24 +164,38 @@ log_accounting(const time_t now, const or_options_t *options)
|
||||
or_state_t *state = get_or_state();
|
||||
char *acc_rcvd = bytes_to_usage(state->AccountingBytesReadInInterval);
|
||||
char *acc_sent = bytes_to_usage(state->AccountingBytesWrittenInInterval);
|
||||
char *acc_used = bytes_to_usage(get_accounting_bytes());
|
||||
uint64_t acc_bytes = options->AccountingMax;
|
||||
char *acc_max;
|
||||
time_t interval_end = accounting_get_end_time();
|
||||
char end_buf[ISO_TIME_LEN + 1];
|
||||
char *remaining = NULL;
|
||||
if (options->AccountingRule == ACCT_SUM)
|
||||
acc_bytes *= 2;
|
||||
acc_max = bytes_to_usage(acc_bytes);
|
||||
format_local_iso_time(end_buf, interval_end);
|
||||
remaining = secs_to_uptime(interval_end - now);
|
||||
|
||||
const char *acc_rule;
|
||||
switch (options->AccountingRule) {
|
||||
case ACCT_MAX: acc_rule = "max";
|
||||
break;
|
||||
case ACCT_SUM: acc_rule = "sum";
|
||||
break;
|
||||
case ACCT_OUT: acc_rule = "out";
|
||||
break;
|
||||
case ACCT_IN: acc_rule = "in";
|
||||
break;
|
||||
default: acc_rule = "max";
|
||||
break;
|
||||
}
|
||||
|
||||
log_notice(LD_HEARTBEAT, "Heartbeat: Accounting enabled. "
|
||||
"Sent: %s / %s, Received: %s / %s. The "
|
||||
"Sent: %s, Received: %s, Used: %s / %s, Rule: %s. The "
|
||||
"current accounting interval ends on %s, in %s.",
|
||||
acc_sent, acc_max, acc_rcvd, acc_max, end_buf, remaining);
|
||||
acc_sent, acc_rcvd, acc_used, acc_max, acc_rule, end_buf, remaining);
|
||||
|
||||
tor_free(acc_rcvd);
|
||||
tor_free(acc_sent);
|
||||
tor_free(acc_used);
|
||||
tor_free(acc_max);
|
||||
tor_free(remaining);
|
||||
}
|
||||
|
@ -61,6 +61,32 @@ test_accounting_limits(void *arg)
|
||||
fake_time += 1;
|
||||
consider_hibernation(fake_time);
|
||||
tor_assert(we_are_hibernating() == 1);
|
||||
|
||||
options->AccountingRule = ACCT_OUT;
|
||||
|
||||
accounting_add_bytes(100, 10, 1);
|
||||
fake_time += 1;
|
||||
consider_hibernation(fake_time);
|
||||
tor_assert(we_are_hibernating() == 0);
|
||||
|
||||
accounting_add_bytes(0, 90, 1);
|
||||
fake_time += 1;
|
||||
consider_hibernation(fake_time);
|
||||
tor_assert(we_are_hibernating() == 1);
|
||||
|
||||
options->AccountingMax = 300;
|
||||
options->AccountingRule = ACCT_IN;
|
||||
|
||||
accounting_add_bytes(10, 100, 1);
|
||||
fake_time += 1;
|
||||
consider_hibernation(fake_time);
|
||||
tor_assert(we_are_hibernating() == 0);
|
||||
|
||||
accounting_add_bytes(90, 0, 1);
|
||||
fake_time += 1;
|
||||
consider_hibernation(fake_time);
|
||||
tor_assert(we_are_hibernating() == 1);
|
||||
|
||||
goto done;
|
||||
done:
|
||||
NS_UNMOCK(get_or_state);
|
||||
|
@ -707,12 +707,13 @@ NS(logv)(int severity, log_domain_mask_t domain,
|
||||
tt_ptr_op(strstr(funcname, "log_accounting"), OP_NE, NULL);
|
||||
tt_ptr_op(suffix, OP_EQ, NULL);
|
||||
tt_str_op(format, OP_EQ,
|
||||
"Heartbeat: Accounting enabled. Sent: %s / %s, Received: %s / %s. "
|
||||
"The current accounting interval ends on %s, in %s.");
|
||||
"Heartbeat: Accounting enabled. Sent: %s, Received: %s, Used: %s / "
|
||||
"%s, Rule: %s. The current accounting interval ends on %s, in %s.");
|
||||
tt_str_op(va_arg(ap, char *), OP_EQ, "0 kB"); /* acc_sent */
|
||||
tt_str_op(va_arg(ap, char *), OP_EQ, "0 kB"); /* acc_max */
|
||||
tt_str_op(va_arg(ap, char *), OP_EQ, "0 kB"); /* acc_rcvd */
|
||||
tt_str_op(va_arg(ap, char *), OP_EQ, "0 kB"); /* acc_used */
|
||||
tt_str_op(va_arg(ap, char *), OP_EQ, "0 kB"); /* acc_max */
|
||||
tt_str_op(va_arg(ap, char *), OP_EQ, "max"); /* acc_rule */
|
||||
/* format_local_iso_time uses local tz, just check mins and secs. */
|
||||
tt_ptr_op(strstr(va_arg(ap, char *), ":01:00"),
|
||||
OP_NE, NULL); /* end_buf */
|
||||
|
Loading…
Reference in New Issue
Block a user