[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
stream_bw event
Mentioned this on irc the other night and took the attached approach.
If you are happy with the general outline, I can prepare a proper patch adding
stuff to the docs etc and with proper comments. There are probably a couple
of house-style solecisms in there too, so please let me know.
I've casually tested it but not to destruction: it works for me so far.
R/W events with 0 bytes are not reported to the controller as per Nick's
suggestion.
--
KlamAV - An Anti-Virus Manager for KDE - http://www.klamav.net
TorK - A Tor Controller For KDE - http://tork.sf.net
Index: src/or/control.c
===================================================================
--- src/or/control.c (revision 9502)
+++ src/or/control.c (working copy)
@@ -89,7 +89,8 @@
#define EVENT_STATUS_SERVER 0x0011
#define EVENT_STATUS_GENERAL 0x0012
#define EVENT_GUARD 0x0013
-#define _EVENT_MAX 0x0013
+#define EVENT_STREAM_BANDWIDTH_USED 0x0014
+#define _EVENT_MAX 0x0014
/* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */
/** Array mapping from message type codes to human-readable message
@@ -1089,6 +1090,8 @@
event_code = EVENT_STATUS_SERVER;
else if (!strcasecmp(ev, "GUARD"))
event_code = EVENT_GUARD;
+ else if (!strcasecmp(ev, "STREAM_BW"))
+ event_code = EVENT_STREAM_BANDWIDTH_USED;
else {
connection_printf_to_buf(conn, "552 Unrecognized event \"%s\"\r\n",
ev);
@@ -3383,6 +3386,44 @@
}
/** A second or more has elapsed: tell any interested control
+ * connections how much bandwidth streams have used. */
+int
+control_event_stream_bandwidth_used()
+{
+ connection_t **carray;
+ edge_connection_t *conn;
+ int n, i;
+ uint32_t justread, justwritten;
+
+ if (EVENT_IS_INTERESTING1(EVENT_STREAM_BANDWIDTH_USED)) {
+
+ get_connection_array(&carray, &n);
+
+ for (i = 0; i < n; ++i) {
+ if (carray[i]->type != CONN_TYPE_AP)
+ continue;
+ conn = TO_EDGE_CONN(carray[i]);
+ justread = conn->n_read - conn->p_read;
+ conn->p_read = conn->n_read;
+ justwritten = conn->n_written - conn->p_written;
+ conn->p_written = conn->n_written;
+
+ if (justread + justwritten == 0)
+ continue;
+
+ send_control1_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
+ "650 STREAM_BW %lu %lu %lu\r\n",
+ (unsigned long)conn->global_identifier,
+ (unsigned long)justread,
+ (unsigned long)justwritten);
+
+ }
+ }
+
+ return 0;
+}
+
+/** A second or more has elapsed: tell any interested control
* connections how much bandwidth we used. */
int
control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
Index: src/or/or.h
===================================================================
--- src/or/or.h (revision 9502)
+++ src/or/or.h (working copy)
@@ -827,6 +827,14 @@
/* XXXX NM This can get re-used after 2**32 streams */
uint32_t global_identifier;
+ /** Bytes read */
+ uint32_t n_read;
+ uint32_t p_read;
+
+ /** Bytes written */
+ uint32_t n_written;
+ uint32_t p_written;
+
/** Exit only: a dirserv connection that is tunneled over this connection
* using a socketpair. */
struct dir_connection_t *bridge_for_conn;
@@ -2324,6 +2332,7 @@
int control_event_or_conn_status(or_connection_t *conn,
or_conn_status_event_t e, int reason);
int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);
+int control_event_stream_bandwidth_used();
void control_event_logmsg(int severity, unsigned int domain, const char *msg);
int control_event_descriptors_changed(smartlist_t *routers);
int control_event_address_mapped(const char *from, const char *to,
Index: src/or/connection.c
===================================================================
--- src/or/connection.c (revision 9502)
+++ src/or/connection.c (working copy)
@@ -1572,6 +1572,13 @@
*max_to_read = at_most - n_read;
}
+ if (CONN_IS_EDGE(conn)) {
+ if (conn->type == CONN_TYPE_AP){
+ edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+ edge_conn->n_read += n_read;
+ }
+ }
+
if (connection_is_rate_limited(conn)) {
/* For non-local IPs, remember if we flushed any bytes over the wire. */
time_t now = time(NULL);
@@ -1768,6 +1775,16 @@
n_written = (size_t) result;
}
+
+ if (CONN_IS_EDGE(conn)) {
+ if (conn->type == CONN_TYPE_AP){
+ edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+ edge_conn->n_written += n_written;
+ }
+ }
+
+
+
if (connection_is_rate_limited(conn)) {
/* For non-local IPs, remember if we flushed any bytes over the wire. */
time_t now = time(NULL);
Index: src/or/main.c
===================================================================
--- src/or/main.c (revision 9502)
+++ src/or/main.c (working copy)
@@ -998,6 +998,7 @@
if (accounting_is_enabled(options) && seconds_elapsed >= 0)
accounting_add_bytes(bytes_read, bytes_written, seconds_elapsed);
control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written);
+ control_event_stream_bandwidth_used();
if (seconds_elapsed > 0)
connection_bucket_refill(seconds_elapsed);