Skip to content

Completely overhaul the tor-proto circuit reactor

eta requested to merge eta/arti:proto-circuit-refactor into main

Rather like e8e9699c ("Get rid of tor-proto's ChannelImpl, and use the reactor more instead"), this admittedly rather large commit refactors the way circuits in tor-proto work, centralising all of the logic in one large nonblocking reactor which other things send messages into and out of, instead of having a bunch of -Impl types that are protected by mutexes.

Congestion control becomes a lot simpler with this refactor, since the reactor can manage both stream- and circuit-level congestion control unilaterally without having to share this information with consumers, meaning we can get rid of some locks.

The way streams work also changes, in order to facilitate better handling of backpressure / fairness between streams: each stream now has a set of channels to send and receive messages over, instead of sending relay cells directly onto the channel (now, the reactor pulls messages off each stream in each map, and tries to avoid doing so if it won't be able to forward them yet).

Additionally, a lot of "close this circuit / stream" messages aren't required any more, since that state is simply indicated by one end of a channel going away. This should make cleanup a lot less brittle.

Getting all of this to work involved writing a fair deal of intricate nonblocking code in Reactor::run_once that tries very hard to be mindful of making backpressure work correctly (and congestion control); the old code could get away with having tasks .await on things, but the new reactor can't really do this (as it'd lock the reactor up), so has to do everything in a nonblocking manner.

This commit doesn't fix the tests yet. That will be hard.

Edited by eta

Merge request reports