aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/circuituse.c38
-rw-r--r--src/or/circuituse.h2
-rw-r--r--src/or/connection_edge.c9
-rw-r--r--src/or/or.h24
-rw-r--r--src/or/relay.c40
-rw-r--r--src/or/rendcommon.c6
6 files changed, 115 insertions, 4 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 47e29c28dd..a584e3eca8 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -3083,3 +3083,41 @@ mark_circuit_unusable_for_new_conns(origin_circuit_t *circ)
circ->unusable_for_new_conns = 1;
}
+/**
+ * Add relay_body_len and RELAY_PAYLOAD_SIZE-relay_body_len to
+ * the valid delivered written fields and the overhead field,
+ * respectively.
+ */
+void
+circuit_sent_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
+{
+ if (!circ) return;
+
+ tor_assert_nonfatal(relay_body_len <= RELAY_PAYLOAD_SIZE);
+
+ circ->n_delivered_written_circ_bw =
+ tor_add_u32_nowrap(circ->n_delivered_written_circ_bw, relay_body_len);
+ circ->n_overhead_written_circ_bw =
+ tor_add_u32_nowrap(circ->n_overhead_written_circ_bw,
+ RELAY_PAYLOAD_SIZE-relay_body_len);
+}
+
+/**
+ * Add relay_body_len and RELAY_PAYLOAD_SIZE-relay_body_len to
+ * the valid delivered read field and the overhead field,
+ * respectively.
+ */
+void
+circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
+{
+ if (!circ) return;
+
+ tor_assert_nonfatal(relay_body_len <= RELAY_PAYLOAD_SIZE);
+
+ circ->n_delivered_read_circ_bw =
+ tor_add_u32_nowrap(circ->n_delivered_read_circ_bw, relay_body_len);
+ circ->n_overhead_read_circ_bw =
+ tor_add_u32_nowrap(circ->n_overhead_read_circ_bw,
+ RELAY_PAYLOAD_SIZE-relay_body_len);
+}
+
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index 71c818b978..6458bd6908 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -65,6 +65,8 @@ void mark_circuit_unusable_for_new_conns(origin_circuit_t *circ);
int circuit_purpose_is_hidden_service(uint8_t);
int circuit_should_use_vanguards(uint8_t);
+void circuit_sent_valid_data(origin_circuit_t *circ, uint16_t relay_body_len);
+void circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len);
#ifdef TOR_UNIT_TESTS
/* Used only by circuituse.c and test_circuituse.c */
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 955f942c50..02f1680ee3 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -3526,10 +3526,17 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
n_stream->deliver_window = STREAMWINDOW_START;
if (circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) {
+ int ret;
tor_free(address);
/* We handle this circuit and stream in this function for all supported
* hidden service version. */
- return handle_hs_exit_conn(circ, n_stream);
+ ret = handle_hs_exit_conn(circ, n_stream);
+
+ if (ret == 0) {
+ /* This was a valid cell. Count it as delivered + overhead. */
+ circuit_read_valid_data(origin_circ, rh.length);
+ }
+ return ret;
}
tor_strlower(address);
n_stream->base_.address = address;
diff --git a/src/or/or.h b/src/or/or.h
index e27f25197b..fc72badb4d 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3250,16 +3250,36 @@ typedef struct origin_circuit_t {
* associated with this circuit. */
edge_connection_t *p_streams;
- /** Bytes read from any attached stream since last call to
+ /** Bytes read on this circuit since last call to
* control_event_circ_bandwidth_used(). Only used if we're configured
* to emit CIRC_BW events. */
uint32_t n_read_circ_bw;
- /** Bytes written to any attached stream since last call to
+ /** Bytes written to on this circuit since last call to
* control_event_circ_bandwidth_used(). Only used if we're configured
* to emit CIRC_BW events. */
uint32_t n_written_circ_bw;
+ /** Total known-valid relay cell bytes since last call to
+ * control_event_circ_bandwidth_used(). Only used if we're configured
+ * to emit CIRC_BW events. */
+ uint32_t n_delivered_read_circ_bw;
+
+ /** Total written relay cell bytes since last call to
+ * control_event_circ_bandwidth_used(). Only used if we're configured
+ * to emit CIRC_BW events. */
+ uint32_t n_delivered_written_circ_bw;
+
+ /** Total overhead data in all known-valid relay data cells since last
+ * call to control_event_circ_bandwidth_used(). Only used if we're
+ * configured to emit CIRC_BW events. */
+ uint32_t n_overhead_read_circ_bw;
+
+ /** Total written overhead data in all relay data cells since last call to
+ * control_event_circ_bandwidth_used(). Only used if we're configured
+ * to emit CIRC_BW events. */
+ uint32_t n_overhead_written_circ_bw;
+
/** Build state for this circuit. It includes the intended path
* length, the chosen exit router, rendezvous information, etc.
*/
diff --git a/src/or/relay.c b/src/or/relay.c
index 8c248e6d98..05f71efead 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -611,6 +611,10 @@ relay_send_command_from_edge_,(streamid_t stream_id, circuit_t *circ,
tor_free(commands);
smartlist_free(commands_list);
}
+
+ /* Let's assume we're well-behaved: Anything that we decide to send is
+ * valid, delivered data. */
+ circuit_sent_valid_data(origin_circ, rh.length);
}
if (circuit_package_relay_cell(&cell, circ, cell_direction, cpath_layer,
@@ -740,6 +744,9 @@ connection_ap_process_end_not_open(
}
}
+ /* This end cell is now valid. */
+ circuit_read_valid_data(circ, rh->length);
+
if (rh->length == 0) {
reason = END_STREAM_REASON_MISC;
}
@@ -1230,6 +1237,12 @@ connection_edge_process_resolved_cell(edge_connection_t *conn,
}
}
+ /* This is valid data at this point. Count it */
+ if (conn->on_circuit && CIRCUIT_IS_ORIGIN(conn->on_circuit)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(conn->on_circuit),
+ rh->length);
+ }
+
connection_ap_handshake_socks_got_resolved_cell(entry_conn,
errcode,
resolved_addresses);
@@ -1326,6 +1339,9 @@ connection_edge_process_relay_cell_not_open(
entry_conn->chosen_exit_name, ttl);
remap_event_helper(entry_conn, &addr);
+
+ /* This is valid data at this point. Count it */
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
}
circuit_log_path(LOG_INFO,LD_APP,TO_ORIGIN_CIRCUIT(circ));
/* don't send a socks reply to transparent conns */
@@ -1496,7 +1512,6 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
circ->dirreq_id = ++next_id;
TO_OR_CIRCUIT(circ)->p_chan->dirreq_id = circ->dirreq_id;
}
-
return connection_exit_begin_conn(cell, circ);
case RELAY_COMMAND_DATA:
++stats_n_data_cells_received;
@@ -1532,6 +1547,10 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
"(relay data) conn deliver_window below 0. Killing.");
return -END_CIRC_REASON_TORPROTOCOL;
}
+ /* Total all valid application bytes delivered */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
stats_n_data_bytes_received += rh.length;
connection_buf_add((char*)(cell->payload + RELAY_HEADER_SIZE),
@@ -1584,6 +1603,11 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
/* only mark it if not already marked. it's possible to
* get the 'end' right around when the client hangs up on us. */
connection_mark_and_flush(TO_CONN(conn));
+
+ /* Total all valid application bytes delivered */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
}
return 0;
case RELAY_COMMAND_EXTEND:
@@ -1649,6 +1673,10 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
log_info(domain,"circuit_send_next_onion_skin() failed.");
return reason;
}
+ /* Total all valid bytes delivered. */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
return 0;
case RELAY_COMMAND_TRUNCATE:
if (layer_hint) {
@@ -1714,6 +1742,16 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
log_debug(LD_APP,"circ-level sendme at origin, packagewindow %d.",
layer_hint->package_window);
circuit_resume_edge_reading(circ, layer_hint);
+
+ /* We count circuit-level sendme's as valid delivered data because
+ * they are rate limited. Note that we cannot count stream
+ * sendme's because the other end could send as many as they like.
+ */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ),
+ rh.length);
+ }
+
} else {
if (circ->package_window + CIRCWINDOW_INCREMENT >
CIRCWINDOW_START_MAX) {
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index 230da4be5c..2a77b2ece7 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -12,6 +12,7 @@
#include "or.h"
#include "circuitbuild.h"
+#include "circuituse.h"
#include "config.h"
#include "control.h"
#include "hs_common.h"
@@ -807,6 +808,11 @@ rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint,
tor_fragile_assert();
}
+ if (r == 0 && origin_circ) {
+ /* This was a valid cell. Count it as delivered + overhead. */
+ circuit_read_valid_data(origin_circ, length);
+ }
+
if (r == -2)
log_info(LD_PROTOCOL, "Dropping cell (type %d) for wrong circuit type.",
command);