diff options
author | Mike Perry <mikeperry-git@torproject.org> | 2018-09-13 01:23:17 +0000 |
---|---|---|
committer | Mike Perry <mikeperry-git@torproject.org> | 2018-09-13 17:45:45 +0000 |
commit | efa20756701b3434fce29b41f7210bc33423d764 (patch) | |
tree | 6af0f09aedc1b4e8e760ef03529215866af65abe | |
parent | 80ffedd3ca78e76e706ef2ac3f469a4fa4aa7a96 (diff) | |
download | tor-efa20756701b3434fce29b41f7210bc33423d764.tar.gz tor-efa20756701b3434fce29b41f7210bc33423d764.zip |
Ticket #27678: Emit CIRC_BW events immediately for dropped cells.
We determine that a cell was dropped by inspecting CIRC_BW fields. If we did
not update the delivered or overhead fields after processing the cell, the
cell was dropped/not processed.
Also emit CIRC_BW events for cases where we decide to close the circuit in
this function, so vanguards can print messages about dropped cells in those
cases, too.
-rw-r--r-- | src/core/or/command.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/core/or/command.c b/src/core/or/command.c index 461e49b629..ebddc4a352 100644 --- a/src/core/or/command.c +++ b/src/core/or/command.c @@ -480,6 +480,8 @@ command_process_relay_cell(cell_t *cell, channel_t *chan) const or_options_t *options = get_options(); circuit_t *circ; int reason, direction; + uint32_t orig_delivered_bw = 0; + uint32_t orig_overhead_bw = 0; circ = circuit_get_by_circid_channel(cell->circ_id, chan); @@ -512,6 +514,15 @@ command_process_relay_cell(cell_t *cell, channel_t *chan) /* Count the payload bytes only. We don't care about cell headers */ ocirc->n_read_circ_bw = tor_add_u32_nowrap(ocirc->n_read_circ_bw, CELL_PAYLOAD_SIZE); + + /* Stash the original delivered and overhead values. These values are + * updated by circuit_read_valid_data() during cell processing by + * connection_edge_process_relay_cell(), called from + * circuit_receive_relay_cell() below. If they do not change, we inform + * the control port about dropped cells immediately after the call + * to circuit_receive_relay_cell() below. */ + orig_delivered_bw = ocirc->n_delivered_read_circ_bw; + orig_overhead_bw = ocirc->n_overhead_read_circ_bw; } if (!CIRCUIT_IS_ORIGIN(circ) && @@ -535,6 +546,8 @@ command_process_relay_cell(cell_t *cell, channel_t *chan) (unsigned)cell->circ_id); if (CIRCUIT_IS_ORIGIN(circ)) { circuit_log_path(LOG_WARN, LD_OR, TO_ORIGIN_CIRCUIT(circ)); + /* Always emit a bandwidth event for closed circs */ + control_event_circ_bandwidth_used_for_circ(TO_ORIGIN_CIRCUIT(circ)); } else if (circ->n_chan) { log_warn(LD_OR, " upstream=%s", channel_get_actual_remote_descr(circ->n_chan)); @@ -560,9 +573,33 @@ command_process_relay_cell(cell_t *cell, channel_t *chan) log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,"circuit_receive_relay_cell " "(%s) failed. Closing.", direction==CELL_DIRECTION_OUT?"forward":"backward"); + /* Always emit a bandwidth event for closed circs */ + if (CIRCUIT_IS_ORIGIN(circ)) { + control_event_circ_bandwidth_used_for_circ(TO_ORIGIN_CIRCUIT(circ)); + } circuit_mark_for_close(circ, -reason); } + if (CIRCUIT_IS_ORIGIN(circ)) { + origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); + + /* If neither the delivered nor overhead values changed, this cell + * was dropped due to being invalid by one of the error codepaths in + * connection_edge_process_relay_cell(), called by + * circuit_receive_relay_cell(). + * + * Valid cells, on the other hand, call circuit_read_valid_data() + * to update these values upon processing them. + * + * So, if the values are the same as those stored above, + * emit a control port event for CIRC_BW, so the controller can + * react quickly to invalid cells. */ + if (orig_delivered_bw == ocirc->n_delivered_read_circ_bw && + orig_overhead_bw == ocirc->n_overhead_read_circ_bw) { + control_event_circ_bandwidth_used_for_circ(ocirc); + } + } + /* If this is a cell in an RP circuit, count it as part of the hidden service stats */ if (options->HiddenServiceStatistics && |