Bug 25903: Perform accounting for new CIRC_BW fields.

Two new values in each direction. DELIVERED counts valid end-to-end circuit
data that is accepted by our end and OVERHEAD counts the slack unused data in
each of the relay command cells for those accepted cells.

Control port changes are in the next commit.
This commit is contained in:
Mike Perry 2018-04-23 20:06:34 +00:00
parent 7b09282dc7
commit e07e95edd3
6 changed files with 115 additions and 4 deletions

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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.
*/

View File

@ -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) {

View File

@ -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);