aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarsten Loesing <karsten.loesing@gmx.net>2013-02-06 14:15:32 +0100
committerKarsten Loesing <karsten.loesing@gmx.net>2013-05-16 13:48:35 +0200
commit8d1f78c556abb570bb80ea84261c954d9746cf33 (patch)
treeab3888a02792bc7a7e04989e7f8035c747f43e93
parente54d664f7bb1205162c1df3495f8ebc30c23d867 (diff)
downloadtor-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.c24
-rw-r--r--src/or/control.c52
-rw-r--r--src/or/control.h2
-rw-r--r--src/or/main.c3
-rw-r--r--src/or/or.h6
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&lt;&lt;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. */