Add new CONN_BW event.

Jointly authored with Rob Jansen <jansen@cs.umn.edu>.
This commit is contained in:
Karsten Loesing 2013-02-06 14:15:32 +01:00
parent e54d664f7b
commit 8d1f78c556
5 changed files with 86 additions and 1 deletions

View file

@ -3148,6 +3148,18 @@ connection_read_to_buf(connection_t *conn, ssize_t *max_to_read,
else else
edge_conn->n_read = UINT32_MAX; 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); 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; 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); connection_buckets_decrement(conn, approx_time(), n_read, n_written);
if (result > 0) { if (result > 0) {

View file

@ -82,7 +82,8 @@
#define EVENT_BUILDTIMEOUT_SET 0x0017 #define EVENT_BUILDTIMEOUT_SET 0x0017
#define EVENT_SIGNAL 0x0018 #define EVENT_SIGNAL 0x0018
#define EVENT_CONF_CHANGED 0x0019 #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. */ /* 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 /** 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_BUILDTIMEOUT_SET, "BUILDTIMEOUT_SET" },
{ EVENT_SIGNAL, "SIGNAL" }, { EVENT_SIGNAL, "SIGNAL" },
{ EVENT_CONF_CHANGED, "CONF_CHANGED"}, { EVENT_CONF_CHANGED, "CONF_CHANGED"},
{ EVENT_CONN_BW, "CONN_BW" },
{ 0, NULL }, { 0, NULL },
}; };
@ -3906,6 +3908,54 @@ control_event_stream_bandwidth_used(void)
return 0; 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 /** A second or more has elapsed: tell any interested control
* connections how much bandwidth we used. */ * connections how much bandwidth we used. */
int int

View file

@ -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_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(edge_connection_t *edge_conn);
int control_event_stream_bandwidth_used(void); 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); void control_event_logmsg(int severity, uint32_t domain, const char *msg);
int control_event_descriptors_changed(smartlist_t *routers); int control_event_descriptors_changed(smartlist_t *routers);
int control_event_address_mapped(const char *from, const char *to, int control_event_address_mapped(const char *from, const char *to,

View file

@ -351,6 +351,8 @@ connection_remove(connection_t *conn)
(int)conn->s, conn_type_to_string(conn->type), (int)conn->s, conn_type_to_string(conn->type),
smartlist_len(connection_array)); smartlist_len(connection_array));
control_event_conn_bandwidth(conn);
tor_assert(conn->conn_array_index >= 0); tor_assert(conn->conn_array_index >= 0);
current_index = conn->conn_array_index; current_index = conn->conn_array_index;
connection_unregister_events(conn); /* This is redundant, but cheap. */ 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_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written);
control_event_stream_bandwidth_used(); control_event_stream_bandwidth_used();
control_event_conn_bandwidth_used();
if (server_mode(options) && if (server_mode(options) &&
!net_is_disabled() && !net_is_disabled() &&

View file

@ -1230,6 +1230,12 @@ typedef struct connection_t {
/** Unique identifier for this connection on this Tor instance. */ /** Unique identifier for this connection on this Tor instance. */
uint64_t global_identifier; 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; } connection_t;
/** Subtype of connection_t; used for a listener socket. */ /** Subtype of connection_t; used for a listener socket. */