tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit ae9a9422099652662c14949a52e9121b17dd9104
parent a30bd40031422589233368dffaf60d9c4fbfa959
Author: Nick Mathewson <nickm@torproject.org>
Date:   Wed, 21 May 2025 13:06:30 -0400

Merge branch 'cgo-fixes-misc' into 'main'

Fix a few bugs from #41051 (CGO cell format)

Closes #41071 and #41070

See merge request tpo/core/tor!892
Diffstat:
Msrc/core/or/conflux.c | 27+++++++++++++++++++++++----
Msrc/core/or/conflux_st.h | 6++++++
Msrc/core/or/relay.c | 15+++++++--------
3 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/src/core/or/conflux.c b/src/core/or/conflux.c @@ -35,7 +35,9 @@ static inline uint64_t cwnd_sendable(const circuit_t *on_circ, uint64_t in_usec, uint64_t our_usec); /* Track the total number of bytes used by all ooo_q so it can be used by the - * OOM handler to assess. */ + * OOM handler to assess. + * + * When adding or subtracting to this value, use conflux_msg_alloc_cost(). */ static uint64_t total_ooo_q_bytes = 0; /** @@ -170,7 +172,8 @@ uint64_t conflux_get_circ_bytes_allocation(const circuit_t *circ) { if (circ->conflux) { - return smartlist_len(circ->conflux->ooo_q) * sizeof(conflux_msg_t); + return smartlist_len(circ->conflux->ooo_q) * sizeof(void*) + + circ->conflux->ooo_q_alloc_cost; } return 0; } @@ -823,6 +826,15 @@ conflux_process_switch_command(circuit_t *in_circ, } /** + * Return the total number of required allocated to store `msg`. + */ +static inline size_t +conflux_msg_alloc_cost(conflux_msg_t *msg) +{ + return msg->msg->length + sizeof(conflux_msg_t) + sizeof(relay_msg_t); +} + +/** * Process an incoming relay cell for conflux. Called from * connection_edge_process_relay_cell(). * @@ -876,10 +888,13 @@ conflux_process_relay_msg(conflux_t *cfx, circuit_t *in_circ, * stack. This is simpler and less error prone but might show up in our * profile (maybe?). The Maze is serious. It needs to be respected. */ c_msg->msg = relay_msg_copy(msg); + size_t cost = conflux_msg_alloc_cost(c_msg); smartlist_pqueue_add(cfx->ooo_q, conflux_queue_cmp, offsetof(conflux_msg_t, heap_idx), c_msg); - total_ooo_q_bytes += sizeof(msg->length); + + total_ooo_q_bytes += cost; + cfx->ooo_q_alloc_cost += cost; /* This cell should not be processed yet, and the queue is not ready * to process because the next absolute seqnum has not yet arrived */ @@ -907,7 +922,11 @@ conflux_dequeue_relay_msg(conflux_t *cfx) if (top->seq == cfx->last_seq_delivered+1) { smartlist_pqueue_pop(cfx->ooo_q, conflux_queue_cmp, offsetof(conflux_msg_t, heap_idx)); - total_ooo_q_bytes -= sizeof(top->msg->length); + + size_t cost = conflux_msg_alloc_cost(top); + total_ooo_q_bytes -= cost; + cfx->ooo_q_alloc_cost -= cost; + cfx->last_seq_delivered++; return top; } else { diff --git a/src/core/or/conflux_st.h b/src/core/or/conflux_st.h @@ -103,6 +103,12 @@ struct conflux_t { smartlist_t *ooo_q; /** + * Approximate allocation cost of the bytes stored in ooo_q + * and the messages that it contains. + */ + size_t ooo_q_alloc_cost; + + /** * Absolute sequence number of cells delivered to streams since start. * (ie: this is updated *after* dequeue from the ooo_q priority queue). */ uint64_t last_seq_delivered; diff --git a/src/core/or/relay.c b/src/core/or/relay.c @@ -2107,12 +2107,11 @@ connection_edge_process_relay_cell(const relay_msg_t *msg, circuit_t *circ, if (conflux_process_relay_msg(circ->conflux, circ, layer_hint, (relay_msg_t *) msg)) { conflux_msg_t *c_msg = NULL; - int ret = 0; /* First, process this cell */ - if ((ret = connection_edge_process_ordered_relay_cell(msg, circ, - conn, - layer_hint) < 0)) { + int ret = connection_edge_process_ordered_relay_cell( + msg, circ, conn, layer_hint); + if (ret < 0) { return ret; } @@ -2120,10 +2119,10 @@ connection_edge_process_relay_cell(const relay_msg_t *msg, circuit_t *circ, while ((c_msg = conflux_dequeue_relay_msg(circ->conflux))) { conn = relay_lookup_conn(circ, c_msg->msg, CELL_DIRECTION_OUT, layer_hint); - if ((ret = - connection_edge_process_ordered_relay_cell(c_msg->msg, circ, - conn, - layer_hint)) < 0) { + ret = connection_edge_process_ordered_relay_cell(c_msg->msg, circ, + conn, + layer_hint); + if (ret < 0) { /* Negative return value is a fatal error. Return early and tear down * circuit */ conflux_relay_msg_free(c_msg);