Properly compute cell-drop overload fraction

Patch to address #40673. An additional check has been added to
onion_pending_add() in order to ensure that we avoid counting create
cells from clients.

In the cpuworker.c assign_onionskin_to_cpuworker
method if total_pending_tasks >= max_pending_tasks
and channel_is_client(circ->p_chan) returns false then
rep_hist_note_circuit_handshake_dropped() will be called and
rep_hist_note_circuit_handshake_assigned() will not be called. This
causes relays to run into errors due to the fact that the number of
dropped packets exceeds the total number of assigned packets.

To avoid this situation a check has been added to
onion_pending_add() to ensure that these erroneous calls to
rep_hist_note_circuit_handshake_dropped() are not made.

See the #40673 ticket for the conversation with armadev about this issue.
This commit is contained in:
Andy 2022-10-06 04:30:18 +00:00 committed by Roger Dingledine
parent 2dff82dc72
commit d09414858e
2 changed files with 13 additions and 1 deletions

7
changes/bug40673 Normal file
View File

@ -0,0 +1,7 @@
o Minor bugfixes (relay overload statistics):
- Count total create cells vs dropped rate cells properly, when
assessing if our fraction of dropped cells is too high. We only
count non-client circuits in the denominator, but we would include
client circuits in the numerator, leading to surprising log lines
claiming that we had dropped more than 100% of incoming create
cells. Fixes bug 40673; bugfix on 0.4.7.1-alpha.

View File

@ -36,6 +36,7 @@
#include "feature/stats/rephist.h"
#include "core/or/or_circuit_st.h"
#include "core/or/channel.h"
/** Type for a linked list of circuits that are waiting for a free CPU worker
* to process a waiting onion handshake. */
@ -188,7 +189,11 @@ onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
#define WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL (60)
static ratelim_t last_warned =
RATELIM_INIT(WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL);
rep_hist_note_circuit_handshake_dropped(queue_idx);
if (!channel_is_client(circ->p_chan)) {
// Avoid counting create cells from clients, to go with the same
// check in command_process_create_cell().
rep_hist_note_circuit_handshake_dropped(queue_idx);
}
if (queue_idx == ONION_HANDSHAKE_TYPE_NTOR) {
char *m;
if ((m = rate_limit_log(&last_warned, approx_time()))) {