tor-proto: Rewrite reactor loop to read from all circuits.

This MR updates the Reactor::run_once() loop to make it read from (and write to) all circuit legs, and not just the primary one.

Note that this slightly changes the behavior of the reactor. Previously, we'd only read from the control channel if the chan_sender was ready, whereas now the control channel is unconditionally read from, in the outer select. The overall effect is that the control channel can cause unbounded buffering in the chan_sender of each circuit (which can happen if the chan_sender is not ready to send). This was actually how the reactor worked before the refactoring from !2747 (merged), which is reflected in the chan_sender docs:

    /// Sender object used to actually send cells.
    ///
    /// NOTE: Control messages could potentially add unboundedly to this, although that's
    ///       not likely to happen (and isn't triggereable from the network, either).
    chan_sender: SometimesUnboundedSink<AnyChanCell, ChannelSender>,

I don't believe this to be a problem, for the reason mentioned in the chan_sender docs, and because the main reason we check for chan_sender readiness is to apply backpressure on senders, which is not something we need to worry about when it comes to the control channel. Besides, the control channel is unbounded, so not reading from it won't stop the senders from sending more commands anyway.

Closes #1863 (closed)

cc @opara @dgoulet

Merge request reports

Loading