diff options
author | Karsten Loesing <karsten.loesing@gmx.net> | 2013-02-06 14:15:32 +0100 |
---|---|---|
committer | Karsten Loesing <karsten.loesing@gmx.net> | 2013-05-16 13:48:35 +0200 |
commit | 8d1f78c556abb570bb80ea84261c954d9746cf33 (patch) | |
tree | ab3888a02792bc7a7e04989e7f8035c747f43e93 | |
parent | e54d664f7bb1205162c1df3495f8ebc30c23d867 (diff) | |
download | tor-8d1f78c556abb570bb80ea84261c954d9746cf33.tar tor-8d1f78c556abb570bb80ea84261c954d9746cf33.tar.gz |
Add new CONN_BW event.
Jointly authored with Rob Jansen <jansen@cs.umn.edu>.
-rw-r--r-- | src/or/connection.c | 24 | ||||
-rw-r--r-- | src/or/control.c | 52 | ||||
-rw-r--r-- | src/or/control.h | 2 | ||||
-rw-r--r-- | src/or/main.c | 3 | ||||
-rw-r--r-- | src/or/or.h | 6 |
5 files changed, 86 insertions, 1 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 87fa79970..81b499160 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -3148,6 +3148,18 @@ connection_read_to_buf(connection_t *conn, ssize_t *max_to_read, else edge_conn->n_read = UINT32_MAX; } + + /* In TestingTorNetwork mode, update conn->n_read for OR/DIR/EXIT + * connections, checking for overflow. */ + if (get_options()->TestingTorNetwork && + (conn->type == CONN_TYPE_OR || + conn->type == CONN_TYPE_DIR || + conn->type == CONN_TYPE_EXIT)) { + if (PREDICT_LIKELY(UINT32_MAX - conn->n_read > n_read)) + conn->n_read += (int)n_read; + else + conn->n_read = UINT32_MAX; + } } connection_buckets_decrement(conn, approx_time(), n_read, n_written); @@ -3594,6 +3606,18 @@ connection_handle_write_impl(connection_t *conn, int force) edge_conn->n_written = UINT32_MAX; } + /* In TestingTorNetwork mode, update conn->n_written for OR/DIR/EXIT + * connections, checking for overflow. */ + if (n_written && get_options()->TestingTorNetwork && + (conn->type == CONN_TYPE_OR || + conn->type == CONN_TYPE_DIR || + conn->type == CONN_TYPE_EXIT)) { + if (PREDICT_LIKELY(UINT32_MAX - conn->n_written > n_written)) + conn->n_written += (int)n_written; + else + conn->n_written = UINT32_MAX; + } + connection_buckets_decrement(conn, approx_time(), n_read, n_written); if (result > 0) { diff --git a/src/or/control.c b/src/or/control.c index 0f202c864..0a49c29d7 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -82,7 +82,8 @@ #define EVENT_BUILDTIMEOUT_SET 0x0017 #define EVENT_SIGNAL 0x0018 #define EVENT_CONF_CHANGED 0x0019 -#define EVENT_MAX_ 0x0019 +#define EVENT_CONN_BW 0x001A +#define EVENT_MAX_ 0x001A /* 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 @@ -958,6 +959,7 @@ static const struct control_event_t control_event_table[] = { { EVENT_BUILDTIMEOUT_SET, "BUILDTIMEOUT_SET" }, { EVENT_SIGNAL, "SIGNAL" }, { EVENT_CONF_CHANGED, "CONF_CHANGED"}, + { EVENT_CONN_BW, "CONN_BW" }, { 0, NULL }, }; @@ -3906,6 +3908,54 @@ control_event_stream_bandwidth_used(void) return 0; } +/** Print out CONN_BW event for a single OR/DIR/EXIT <b>conn</b> and reset + * bandwidth counters. */ +int +control_event_conn_bandwidth(connection_t *conn) +{ + const char *conn_type_str; + if (!get_options()->TestingTorNetwork || + !EVENT_IS_INTERESTING(EVENT_CONN_BW)) + return 0; + if (!conn->n_read && !conn->n_written) + return 0; + switch (conn->type) { + case CONN_TYPE_OR: + conn_type_str = "OR"; + break; + case CONN_TYPE_DIR: + conn_type_str = "DIR"; + break; + case CONN_TYPE_EXIT: + conn_type_str = "EXIT"; + break; + default: + return 0; + } + send_control_event(EVENT_CONN_BW, ALL_FORMATS, + "650 CONN_BW ID="U64_FORMAT" TYPE=%s " + "READ=%lu WRITTEN=%lu\r\n", + U64_PRINTF_ARG(conn->global_identifier), + conn_type_str, + (unsigned long)conn->n_read, + (unsigned long)conn->n_written); + conn->n_written = conn->n_read = 0; + return 0; +} + +/** A second or more has elapsed: tell any interested control + * connections how much bandwidth connections have used. */ +int +control_event_conn_bandwidth_used(void) +{ + if (get_options()->TestingTorNetwork && + EVENT_IS_INTERESTING(EVENT_CONN_BW)) { + SMARTLIST_FOREACH(get_connection_array(), connection_t *, conn, + control_event_conn_bandwidth(conn)); + } + return 0; +} + /** A second or more has elapsed: tell any interested control * connections how much bandwidth we used. */ int diff --git a/src/or/control.h b/src/or/control.h index 61062da2c..fe5c0efa6 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -50,6 +50,8 @@ int control_event_or_conn_status(or_connection_t *conn, int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written); int control_event_stream_bandwidth(edge_connection_t *edge_conn); int control_event_stream_bandwidth_used(void); +int control_event_conn_bandwidth(connection_t *conn); +int control_event_conn_bandwidth_used(void); void control_event_logmsg(int severity, uint32_t domain, const char *msg); int control_event_descriptors_changed(smartlist_t *routers); int control_event_address_mapped(const char *from, const char *to, diff --git a/src/or/main.c b/src/or/main.c index fd8b6cf67..c145f9dfd 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -351,6 +351,8 @@ connection_remove(connection_t *conn) (int)conn->s, conn_type_to_string(conn->type), smartlist_len(connection_array)); + control_event_conn_bandwidth(conn); + tor_assert(conn->conn_array_index >= 0); current_index = conn->conn_array_index; connection_unregister_events(conn); /* This is redundant, but cheap. */ @@ -1638,6 +1640,7 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg) control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written); control_event_stream_bandwidth_used(); + control_event_conn_bandwidth_used(); if (server_mode(options) && !net_is_disabled() && diff --git a/src/or/or.h b/src/or/or.h index 7b6c65fbb..08a94aae6 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1230,6 +1230,12 @@ typedef struct connection_t { /** Unique identifier for this connection on this Tor instance. */ uint64_t global_identifier; + + /** Bytes read since last call to control_event_conn_bandwidth_used() */ + uint32_t n_read; + + /** Bytes written since last call to control_event_conn_bandwidth_used() */ + uint32_t n_written; } connection_t; /** Subtype of connection_t; used for a listener socket. */ |