From 2925e2fe786dfd9a27c2dff503996712cd180de4 Mon Sep 17 00:00:00 2001 From: Karsten Loesing Date: Sun, 24 Feb 2013 13:32:57 +0100 Subject: Add new CIRC_BW event. --- src/or/connection.c | 23 ++++++++++++++++++++- src/or/control.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/or/control.h | 1 + src/or/main.c | 1 + src/or/or.h | 9 +++++++++ 5 files changed, 86 insertions(+), 6 deletions(-) (limited to 'src/or') diff --git a/src/or/connection.c b/src/or/connection.c index dfcd1ab21..a00351a77 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -3203,14 +3203,25 @@ connection_read_to_buf(connection_t *conn, ssize_t *max_to_read, /* change *max_to_read */ *max_to_read = at_most - n_read; - /* Update edge_conn->n_read */ + /* Update edge_conn->n_read and ocirc->n_read */ if (conn->type == CONN_TYPE_AP) { edge_connection_t *edge_conn = TO_EDGE_CONN(conn); + circuit_t *circ = circuit_get_by_edge_conn(edge_conn); + origin_circuit_t *ocirc; + /* Check for overflow: */ if (PREDICT_LIKELY(UINT32_MAX - edge_conn->n_read > n_read)) edge_conn->n_read += (int)n_read; else edge_conn->n_read = UINT32_MAX; + + if (circ && CIRCUIT_IS_ORIGIN(circ)) { + ocirc = TO_ORIGIN_CIRCUIT(circ); + if (PREDICT_LIKELY(UINT32_MAX - ocirc->n_read > n_read)) + ocirc->n_read += (int)n_read; + else + ocirc->n_read = UINT32_MAX; + } } /* In TestingTorNetwork mode, update conn->n_read for OR/DIR/EXIT @@ -3662,12 +3673,22 @@ connection_handle_write_impl(connection_t *conn, int force) if (n_written && conn->type == CONN_TYPE_AP) { edge_connection_t *edge_conn = TO_EDGE_CONN(conn); + circuit_t *circ = circuit_get_by_edge_conn(edge_conn); + origin_circuit_t *ocirc; /* Check for overflow: */ if (PREDICT_LIKELY(UINT32_MAX - edge_conn->n_written > n_written)) edge_conn->n_written += (int)n_written; else edge_conn->n_written = UINT32_MAX; + + if (circ && CIRCUIT_IS_ORIGIN(circ)) { + ocirc = TO_ORIGIN_CIRCUIT(circ); + if (PREDICT_LIKELY(UINT32_MAX - ocirc->n_written > n_written)) + ocirc->n_written += (int)n_written; + else + ocirc->n_written = UINT32_MAX; + } } /* In TestingTorNetwork mode, update conn->n_written for OR/DIR/EXIT diff --git a/src/or/control.c b/src/or/control.c index 47d08c295..d3b968cde 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -46,6 +46,8 @@ #include #endif +extern circuit_t *global_circuitlist; /* from circuitlist.c */ + #include "procmon.h" /** Yield true iff s is the state of a control_connection_t that has @@ -85,7 +87,8 @@ #define EVENT_CONN_BW 0x001A #define EVENT_CELL_STATS 0x001B #define EVENT_TB_EMPTY 0x001C -#define EVENT_MAX_ 0x001C +#define EVENT_CIRC_BANDWIDTH_USED 0x001D +#define EVENT_MAX_ 0x001D /* If EVENT_MAX_ ever hits 0x0020, we need to make the mask wider. */ /** Bitfield: The bit 1<<e is set if any open control @@ -260,8 +263,8 @@ control_update_global_event_mask(void) * we want to hear...*/ control_adjust_event_log_severity(); - /* ...then, if we've started logging stream bw, clear the appropriate - * fields. */ + /* ...then, if we've started logging stream or circ bw, clear the + * appropriate fields. */ if (! (old_mask & EVENT_STREAM_BANDWIDTH_USED) && (new_mask & EVENT_STREAM_BANDWIDTH_USED)) { SMARTLIST_FOREACH(conns, connection_t *, conn, @@ -272,6 +275,17 @@ control_update_global_event_mask(void) } }); } + if (! (old_mask & EVENT_CIRC_BANDWIDTH_USED) && + (new_mask & EVENT_CIRC_BANDWIDTH_USED)) { + circuit_t *circ; + origin_circuit_t *ocirc; + for (circ = global_circuitlist; circ; circ = circ->next) { + if (!CIRCUIT_IS_ORIGIN(circ)) + continue; + ocirc = TO_ORIGIN_CIRCUIT(circ); + ocirc->n_written = ocirc->n_read = 0; + } + } } /** Adjust the log severities that result in control_event_logmsg being called @@ -964,6 +978,7 @@ static const struct control_event_t control_event_table[] = { { EVENT_CONN_BW, "CONN_BW" }, { EVENT_CELL_STATS, "CELL_STATS" }, { EVENT_TB_EMPTY, "TB_EMPTY" }, + { EVENT_CIRC_BANDWIDTH_USED, "CIRC_BW" }, { 0, NULL }, }; @@ -3865,6 +3880,8 @@ control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t tp, int control_event_stream_bandwidth(edge_connection_t *edge_conn) { + circuit_t *circ; + origin_circuit_t *ocirc; if (EVENT_IS_INTERESTING(EVENT_STREAM_BANDWIDTH_USED)) { if (!edge_conn->n_read && !edge_conn->n_written) return 0; @@ -3875,6 +3892,12 @@ control_event_stream_bandwidth(edge_connection_t *edge_conn) (unsigned long)edge_conn->n_read, (unsigned long)edge_conn->n_written); + circ = circuit_get_by_edge_conn(edge_conn); + if (circ && CIRCUIT_IS_ORIGIN(circ)) { + ocirc = TO_ORIGIN_CIRCUIT(circ); + ocirc->n_read += edge_conn->n_read; + ocirc->n_written += edge_conn->n_written; + } edge_conn->n_written = edge_conn->n_read = 0; } @@ -3912,6 +3935,33 @@ control_event_stream_bandwidth_used(void) return 0; } +/** A second or more has elapsed: tell any interested control connections + * how much bandwidth origin circuits have used. */ +int +control_event_circ_bandwidth_used(void) +{ + circuit_t *circ; + origin_circuit_t *ocirc; + if (!EVENT_IS_INTERESTING(EVENT_CIRC_BANDWIDTH_USED)) + return 0; + + for (circ = global_circuitlist; circ; circ = circ->next) { + if (!CIRCUIT_IS_ORIGIN(circ)) + continue; + ocirc = TO_ORIGIN_CIRCUIT(circ); + if (!ocirc->n_read && !ocirc->n_written) + continue; + send_control_event(EVENT_CIRC_BANDWIDTH_USED, ALL_FORMATS, + "650 CIRC_BW ID=%d READ=%lu WRITTEN=%lu\r\n", + ocirc->global_identifier, + (unsigned long)ocirc->n_read, + (unsigned long)ocirc->n_written); + ocirc->n_written = ocirc->n_read = 0; + } + + return 0; +} + /** Print out CONN_BW event for a single OR/DIR/EXIT conn and reset * bandwidth counters. */ int @@ -3960,8 +4010,6 @@ control_event_conn_bandwidth_used(void) return 0; } -extern circuit_t *global_circuitlist; - /** Convert the cell command into a lower-case, human-readable * string. */ static const char * diff --git a/src/or/control.h b/src/or/control.h index 2977159b9..06a384949 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -50,6 +50,7 @@ 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_circ_bandwidth_used(void); int control_event_conn_bandwidth(connection_t *conn); int control_event_conn_bandwidth_used(void); int control_event_circuit_cell_stats(void); diff --git a/src/or/main.c b/src/or/main.c index ae6054830..d38167789 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1641,6 +1641,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(); + control_event_circ_bandwidth_used(); control_event_circuit_cell_stats(); if (server_mode(options) && diff --git a/src/or/or.h b/src/or/or.h index c2be28291..d41034cb7 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2967,6 +2967,15 @@ typedef struct origin_circuit_t { /** Linked list of AP streams (or EXIT streams if hidden service) * associated with this circuit. */ edge_connection_t *p_streams; + + /** Bytes read from any attached stream since last call to + * control_event_circ_bandwidth_used() */ + uint32_t n_read; + + /** Bytes written to any attached stream since last call to + * control_event_circ_bandwidth_used() */ + uint32_t n_written; + /** Build state for this circuit. It includes the intended path * length, the chosen exit router, rendezvous information, etc. */ -- cgit v1.2.3