diff options
author | Karsten Loesing <karsten.loesing@gmx.net> | 2013-02-06 14:26:11 +0100 |
---|---|---|
committer | Karsten Loesing <karsten.loesing@gmx.net> | 2013-05-16 14:18:08 +0200 |
commit | dd5ce2157d8c47ffa3686b0579813e7b1aae8069 (patch) | |
tree | 0d56a4aec246abf38d06df55655262f942f2e6c1 /src/or/control.c | |
parent | c386d2d6ce4c4f58163acb385c7a5de1da8c5e30 (diff) | |
download | tor-dd5ce2157d8c47ffa3686b0579813e7b1aae8069.tar.gz tor-dd5ce2157d8c47ffa3686b0579813e7b1aae8069.zip |
Add new TB_EMPTY event.
Jointly authored with Rob Jansen <jansen@cs.umn.edu>.
Diffstat (limited to 'src/or/control.c')
-rw-r--r-- | src/or/control.c | 102 |
1 files changed, 101 insertions, 1 deletions
diff --git a/src/or/control.c b/src/or/control.c index 66258775e9..47d08c295e 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -84,7 +84,8 @@ #define EVENT_CONF_CHANGED 0x0019 #define EVENT_CONN_BW 0x001A #define EVENT_CELL_STATS 0x001B -#define EVENT_MAX_ 0x001B +#define EVENT_TB_EMPTY 0x001C +#define EVENT_MAX_ 0x001C /* If EVENT_MAX_ ever hits 0x0020, we need to make the mask wider. */ /** Bitfield: The bit 1<<e is set if <b>any</b> open control @@ -962,6 +963,7 @@ static const struct control_event_t control_event_table[] = { { EVENT_CONF_CHANGED, "CONF_CHANGED"}, { EVENT_CONN_BW, "CONN_BW" }, { EVENT_CELL_STATS, "CELL_STATS" }, + { EVENT_TB_EMPTY, "TB_EMPTY" }, { 0, NULL }, }; @@ -4119,6 +4121,104 @@ control_event_circuit_cell_stats(void) return 0; } +/** Helper: return the time in millis that a given bucket was empty, + * capped at the time in millis since last refilling that bucket. Return + * 0 if the bucket was not empty during the last refill period. */ +static uint32_t +bucket_millis_empty(int prev_tokens, uint32_t last_empty_time, + uint32_t milliseconds_elapsed) +{ + uint32_t result = 0, refilled; + if (prev_tokens <= 0) { + struct timeval tvnow; + tor_gettimeofday_cached(&tvnow); + refilled = (uint32_t)((tvnow.tv_sec % 86400L) * 1000L + + (uint32_t)tvnow.tv_usec / (uint32_t)1000L); + result = (uint32_t)((refilled + 86400L * 1000L - last_empty_time) % + (86400L * 1000L)); + if (result > milliseconds_elapsed) + result = milliseconds_elapsed; + } + return result; +} + +/** Token buckets have been refilled: tell any interested control + * connections how global and relay token buckets have changed. */ +int +control_event_refill_global(int global_read, int prev_global_read, + uint32_t global_read_emptied_time, + int global_write, int prev_global_write, + uint32_t global_write_emptied_time, + int relay_read, int prev_relay_read, + uint32_t relay_read_emptied_time, + int relay_write, int prev_relay_write, + uint32_t relay_write_emptied_time, + uint32_t milliseconds_elapsed) +{ + uint32_t global_read_empty_time, global_write_empty_time, + relay_read_empty_time, relay_write_empty_time; + if (!get_options()->TestingTorNetwork || + !EVENT_IS_INTERESTING(EVENT_TB_EMPTY)) + return 0; + if (prev_global_read == global_read && + prev_global_write == global_write && + prev_relay_read == relay_read && + prev_relay_write == relay_write) + return 0; + if (prev_global_read <= 0 && prev_global_write <= 0) { + global_read_empty_time = bucket_millis_empty(prev_global_read, + global_read_emptied_time, milliseconds_elapsed); + global_write_empty_time = bucket_millis_empty(prev_global_write, + global_write_emptied_time, milliseconds_elapsed); + send_control_event(EVENT_TB_EMPTY, ALL_FORMATS, + "650 TB_EMPTY GLOBAL READ=%d WRITTEN=%d " + "LAST=%d\r\n", + global_read_empty_time, global_write_empty_time, + milliseconds_elapsed); + } + if (prev_relay_read <= 0 && prev_relay_write <= 0) { + relay_read_empty_time = bucket_millis_empty(prev_relay_read, + relay_read_emptied_time, milliseconds_elapsed); + relay_write_empty_time = bucket_millis_empty(prev_relay_write, + relay_write_emptied_time, milliseconds_elapsed); + send_control_event(EVENT_TB_EMPTY, ALL_FORMATS, + "650 TB_EMPTY RELAY READ=%d WRITTEN=%d " + "LAST=%d\r\n", + relay_read_empty_time, relay_write_empty_time, + milliseconds_elapsed); + } + return 0; +} + +/** Token buckets of a connection have been refilled: tell any interested + * control connections how per-connection token buckets have changed. */ +int +control_event_refill_conn(or_connection_t *or_conn, + int prev_read, int prev_write, + uint32_t milliseconds_elapsed) +{ + uint32_t read_bucket_empty_time, write_bucket_empty_time; + if (!get_options()->TestingTorNetwork || + !EVENT_IS_INTERESTING(EVENT_TB_EMPTY)) + return 0; + if (prev_read == or_conn->read_bucket && + prev_write == or_conn->write_bucket) + return 0; + if (prev_read <= 0 || prev_write <= 0) { + read_bucket_empty_time = bucket_millis_empty(prev_read, + or_conn->read_emptied_time, milliseconds_elapsed); + write_bucket_empty_time = bucket_millis_empty(prev_write, + or_conn->write_emptied_time, milliseconds_elapsed); + send_control_event(EVENT_TB_EMPTY, ALL_FORMATS, + "650 TB_EMPTY ORCONN ID="U64_FORMAT" READ=%d " + "WRITTEN=%d LAST=%d\r\n", + U64_PRINTF_ARG(or_conn->base_.global_identifier), + read_bucket_empty_time, write_bucket_empty_time, + milliseconds_elapsed); + } + return 0; +} + /** A second or more has elapsed: tell any interested control * connections how much bandwidth we used. */ int |