diff options
-rw-r--r-- | src/or/control.c | 71 | ||||
-rw-r--r-- | src/or/control.h | 3 | ||||
-rw-r--r-- | src/or/main.c | 19 |
3 files changed, 76 insertions, 17 deletions
diff --git a/src/or/control.c b/src/or/control.c index 695f0779cf..d653a520b2 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1,3 +1,4 @@ + /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ @@ -112,6 +113,10 @@ static int disable_log_messages = 0; #define EVENT_IS_INTERESTING(e) \ (!! (global_event_mask & EVENT_MASK_(e))) +/** Macro: true if any event from the bitfield 'e' is interesting. */ +#define ANY_EVENT_IS_INTERESTING(e) \ + EVENT_IS_INTERESTING(e) + /** If we're using cookie-type authentication, how long should our cookies be? */ #define AUTHENTICATION_COOKIE_LEN 32 @@ -219,6 +224,7 @@ static void set_cached_network_liveness(int liveness); static void flush_queued_events_cb(mainloop_event_t *event, void *arg); static char * download_status_to_string(const download_status_t *dl); +static void control_get_bytes_rw_last_sec(uint64_t *r, uint64_t *w); /** Given a control event code for a message event, return the corresponding * log severity. */ @@ -306,6 +312,10 @@ control_update_global_event_mask(void) if (NEWLY_ENABLED(EVENT_CIRC_BANDWIDTH_USED)) { clear_circ_bw_fields(); } + if (NEWLY_ENABLED(EVENT_BANDWIDTH_USED)) { + uint64_t r, w; + control_get_bytes_rw_last_sec(&r, &w); + } #undef NEWLY_ENABLED } @@ -355,6 +365,65 @@ control_event_is_interesting(int event) return EVENT_IS_INTERESTING(event); } +/** Return true if any event that needs to fire once a second is enabled. */ +int +control_any_per_second_event_enabled(void) +{ + return ANY_EVENT_IS_INTERESTING( + EVENT_BANDWIDTH_USED | + EVENT_CELL_STATS | + EVENT_CIRC_BANDWIDTH_USED | + EVENT_CONN_BW | + EVENT_STREAM_BANDWIDTH_USED + ); +} + +/* The value of 'get_bytes_read()' the previous time that + * control_get_bytes_rw_last_sec() as called. */ +static uint64_t stats_prev_n_read = 0; +/* The value of 'get_bytes_written()' the previous time that + * control_get_bytes_rw_last_sec() as called. */ +static uint64_t stats_prev_n_written = 0; + +/** + * Set <b>n_read</b> and <b>n_written</b> to the total number of bytes read + * and written by Tor since the last call to this function. + * + * Call this only from the main thread. + */ +static void +control_get_bytes_rw_last_sec(uint64_t *n_read, + uint64_t *n_written) +{ + const uint64_t stats_n_bytes_read = get_bytes_read(); + const uint64_t stats_n_bytes_written = get_bytes_written(); + + *n_read = stats_n_bytes_read - stats_prev_n_read; + *n_written = stats_n_bytes_written - stats_prev_n_written; + stats_prev_n_read = stats_n_bytes_read; + stats_prev_n_written = stats_n_bytes_written; +} + +/** + * Run all the controller events (if any) that are scheduled to trigger once + * per second. + */ +void +control_per_second_events(void) +{ + if (!control_any_per_second_event_enabled()) + return; + + uint64_t bytes_read, bytes_written; + control_get_bytes_rw_last_sec(&bytes_read, &bytes_written); + control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written); + + control_event_stream_bandwidth_used(); + control_event_conn_bandwidth_used(); + control_event_circ_bandwidth_used(); + control_event_circuit_cell_stats(); +} + /** Append a NUL-terminated string <b>s</b> to the end of * <b>conn</b>-\>outbuf. */ @@ -7609,6 +7678,8 @@ control_free_all(void) { smartlist_t *queued_events = NULL; + stats_prev_n_read = stats_prev_n_written = 0; + if (authentication_cookie) /* Free the auth cookie */ tor_free(authentication_cookie); if (detached_onion_services) { /* Free the detached onion services */ diff --git a/src/or/control.h b/src/or/control.h index 7f8a0bdb5f..92cbf866dd 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -40,6 +40,9 @@ int connection_control_process_inbuf(control_connection_t *conn); #define EVENT_NS 0x000F int control_event_is_interesting(int event); +void control_per_second_events(void); +int control_any_per_second_event_enabled(void); + int control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t e, int reason); int control_event_circuit_purpose_changed(origin_circuit_t *circ, diff --git a/src/or/main.c b/src/or/main.c index c3505a2d91..8929931eb8 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -163,11 +163,6 @@ token_bucket_rw_t global_bucket; /* Token bucket for relayed traffic. */ token_bucket_rw_t global_relayed_bucket; -/* DOCDOC stats_prev_n_read */ -static uint64_t stats_prev_n_read = 0; -/* DOCDOC stats_prev_n_written */ -static uint64_t stats_prev_n_written = 0; - /* XXX we might want to keep stats about global_relayed_*_bucket too. Or not.*/ /** How many bytes have we read since we started the process? */ static uint64_t stats_n_bytes_read = 0; @@ -2508,8 +2503,6 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg) * could use Libevent's timers for this rather than checking the current * time against a bunch of timeouts every second. */ time_t now; - size_t bytes_written; - size_t bytes_read; int seconds_elapsed; (void)timer; (void)arg; @@ -2522,16 +2515,9 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg) /* the second has rolled over. check more stuff. */ seconds_elapsed = current_second ? (int)(now - current_second) : 0; - bytes_read = (size_t)(stats_n_bytes_read - stats_prev_n_read); - bytes_written = (size_t)(stats_n_bytes_written - stats_prev_n_written); - stats_prev_n_read = stats_n_bytes_read; - stats_prev_n_written = stats_n_bytes_written; - control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written); - control_event_stream_bandwidth_used(); - control_event_conn_bandwidth_used(); - control_event_circ_bandwidth_used(); - control_event_circuit_cell_stats(); + /* Maybe some controller events are ready to fire */ + control_per_second_events(); /** If more than this many seconds have elapsed, probably the clock * jumped: doesn't count. */ @@ -3651,7 +3637,6 @@ tor_free_all(int postfork) memset(&global_bucket, 0, sizeof(global_bucket)); memset(&global_relayed_bucket, 0, sizeof(global_relayed_bucket)); - stats_prev_n_read = stats_prev_n_written = 0; stats_n_bytes_read = stats_n_bytes_written = 0; time_of_process_start = 0; time_of_last_signewnym = 0; |