1
//! A circuit's view of the backward state of the circuit.
2

            
3
use crate::channel::Channel;
4
use crate::circuit::UniqId;
5
use crate::circuit::cell_sender::CircuitCellSender;
6
use crate::circuit::reactor::ControlHandler;
7
use crate::circuit::reactor::circhop::CircHopList;
8
use crate::circuit::reactor::macros::derive_deftly_template_CircuitReactor;
9
use crate::circuit::reactor::stream::ReadyStreamMsg;
10
use crate::congestion::{CongestionControl, sendme};
11
use crate::crypto::cell::RelayCellBody;
12
use crate::util::err::ReactorError;
13
use crate::util::poll_all::PollAll;
14
use crate::{Error, HopNum, Result};
15

            
16
// TODO(circpad): once padding is stabilized, the padding module will be moved out of client.
17
use crate::client::circuit::padding::{
18
    self, PaddingController, PaddingEvent, PaddingEventStream, QueuedCellPaddingInfo,
19
};
20

            
21
use tor_cell::chancell::msg::{AnyChanMsg, Relay};
22
use tor_cell::chancell::{AnyChanCell, BoxedCellBody, ChanCmd, CircId};
23
use tor_cell::relaycell::msg::{Sendme, SendmeTag};
24
use tor_cell::relaycell::{AnyRelayMsgOuter, RelayCellFormat, RelayCmd};
25
use tor_error::internal;
26
use tor_rtcompat::{DynTimeProvider, Runtime};
27

            
28
use derive_deftly::Deftly;
29
use futures::SinkExt;
30
use futures::channel::mpsc;
31
use futures::{FutureExt as _, StreamExt, future, select_biased};
32
use tracing::{debug, trace};
33

            
34
use std::pin::Pin;
35
use std::result::Result as StdResult;
36
use std::sync::{Arc, Mutex, RwLock};
37

            
38
use crate::circuit::CircuitRxReceiver;
39

            
40
#[cfg(feature = "circ-padding")]
41
use crate::circuit::padding::{CircPaddingDisposition, padding_disposition};
42

            
43
#[cfg(feature = "relay")]
44
use tor_cell::relaycell::msg::Extended2;
45

            
46
/// The "backward" circuit reactor of a relay.
47
///
48
/// See the [`reactor`](crate::circuit::reactor) module-level docs.
49
///
50
/// Shuts downs down if an error occurs, or if the [`Reactor`](super::Reactor),
51
/// [`ForwardReactor`](super::ForwardReactor), or if one of the
52
/// [`StreamReactor`](super::stream::StreamReactor)s of this circuit shuts down:
53
///
54
///   * if the `Reactor` shuts down, we are alerted via the ctrl/command mpsc channels
55
///     (their sending ends will close, which causes run_once() to return ReactorError::Shutdown)
56
///   * if `ForwardReactor` shuts down, the `Reactor` will notice and will itself shut down,
57
///     which, in turn, causes the `BackwardReactor` to shut down as described above
58
///   * if one of the `StreamReactor`s shuts down, the `ForwardReactor` will
59
///     notice when it next tries to deliver a stream message to it, and shut down,
60
///     causing the `BackwardReactor` and top-level `Reactor` to follow suit
61
#[derive(Deftly)]
62
#[derive_deftly(CircuitReactor)]
63
#[deftly(reactor_name = "backward reactor")]
64
#[deftly(run_inner_fn = "Self::run_once")]
65
#[must_use = "If you don't call run() on a reactor, the circuit won't work."]
66
pub(super) struct BackwardReactor<B: BackwardHandler> {
67
    /// The time provider.
68
    time_provider: DynTimeProvider,
69
    /// An identifier for logging about this reactor's circuit.
70
    unique_id: UniqId,
71
    /// The circuit identifier on the backward Tor channel.
72
    circ_id: CircId,
73
    /// The inbound Tor channel.
74
    channel: Arc<Channel>,
75
    /// Implementation-dependent part of the reactor.
76
    ///
77
    /// This enables us to customize the behavior of the reactor,
78
    /// depending on whether we are a client or a relay.
79
    inner: B,
80
    /// The reading end of the outbound Tor channel, if we are not the last hop.
81
    ///
82
    /// Yields cells moving from the exit towards the client, if we are a middle relay.
83
    outbound_chan_rx: Option<CircuitRxReceiver>,
84
    /// The per-hop state, shared with the forward reactor.
85
    ///
86
    /// The backward reactor acquires a read lock to this whenever it needs to
87
    ///
88
    ///   * send a circuit-level SENDME
89
    ///   * handle a circuit-level SENDME
90
    ///   * send a padding cell
91
    ///
92
    // Note: For the sending/handling of SENDMEs, we lock the hop list
93
    // to extract the relay cell format and CC state of the hop.
94
    // Technically, for the SENDME cases, we could've avoided locking
95
    // the hop list from the BWD, by having the FWD share the relay cell format
96
    // and CC state in the BackwardReactorCmd::{Send,Handle}Sendme command.
97
    // But for the padding case, we *need* the hop list, because we need
98
    // to work out what relay cell format to use when sending the padding cell.
99
    // But for the sake of simplicity, I made the BWD consult the CircHopList in all cases.
100
    //
101
    // TODO: the backward reactor only ever reads from this.
102
    // Conceptually, it is the forward reactor's HopMgr that owns this list:
103
    // only HopMgr can add hops to the list.
104
    //
105
    // Perhaps we need a specialized abstraction that only allows reading here.
106
    // This could be a wrapper over RwLock, providing a read-only API.
107
    hops: Arc<RwLock<CircHopList>>,
108
    /// The sending end of the backward Tor channel.
109
    ///
110
    /// Delivers cells towards the other endpoint: towards the client, if we are a relay,
111
    /// or towards the exit, if we are a client.
112
    inbound_chan_tx: CircuitCellSender,
113
    /// Channel for receiving control commands.
114
    command_rx: mpsc::UnboundedReceiver<CtrlCmd<B::CtrlCmd>>,
115
    /// Channel for receiving control messages.
116
    control_rx: mpsc::UnboundedReceiver<CtrlMsg<B::CtrlMsg>>,
117
    /// Receiver for [`BackwardReactorCmd`]s coming from the forward reactor.
118
    ///
119
    /// The sender is in [`ForwardReactor`](super::ForwardReactor), which will forward all cells
120
    /// carrying Tor stream data to us.
121
    ///
122
    /// This serves a dual purpose:
123
    ///
124
    ///   * it enables the `ForwardReactor` to deliver Tor stream data received
125
    ///     from the other endpoint
126
    ///   * it lets the `BackwardReactor` know if the `ForwardReactor` has shut down:
127
    ///     we select! on this MPSC channel in the main loop, so if the `ForwardReactor`
128
    ///     shuts down, we will get EOS upon calling `.next()`)
129
    forward_reactor_rx: mpsc::Receiver<BackwardReactorCmd>,
130
    /// A channel for receiving endpoint-bound stream messages from the StreamReactor(s)
131
    /// (the stream messages are client-bound if we are a relay, or exit-bound if we are a client).
132
    stream_rx: mpsc::Receiver<ReadyStreamMsg>,
133
    /// A padding controller to which padding-related events should be reported.
134
    padding_ctrl: PaddingController,
135
    /// An event stream telling us about padding-related events.
136
    padding_event_stream: PaddingEventStream,
137
    /// Current rules for blocking traffic, according to the padding controller.
138
    #[cfg(feature = "circ-padding")]
139
    padding_block: Option<padding::StartBlocking>,
140
}
141

            
142
/// A control message aimed at the generic forward reactor.
143
pub(crate) enum CtrlMsg<M> {
144
    /// An implementation-dependent control message.
145
    #[allow(unused)] // TODO(relay)
146
    Custom(M),
147
}
148

            
149
/// A control command aimed at the generic forward reactor.
150
pub(crate) enum CtrlCmd<C> {
151
    /// An implementation-dependent control command.
152
    #[allow(unused)] // TODO(relay)
153
    Custom(C),
154
}
155

            
156
/// Trait for customizing the behavior of the backward reactor.
157
///
158
/// Used for plugging in the implementation-dependent (client vs relay)
159
/// parts of the implementation into the generic one.
160
pub(crate) trait BackwardHandler: ControlHandler {
161
    /// The subclass of ChanMsg that can arrive on this type of circuit.
162
    type CircChanMsg: TryFrom<AnyChanMsg, Error = crate::Error> + Send;
163

            
164
    /// Encrypt a RelayCellBody that is moving in the backward direction.
165
    fn encrypt_relay_cell(
166
        &mut self,
167
        cmd: ChanCmd,
168
        body: &mut RelayCellBody,
169
        hop: Option<HopNum>,
170
    ) -> SendmeTag;
171

            
172
    /// Handle a cell that was read from the Tor outbound channel.
173
    ///
174
    /// Returns an error if the cell should cause the reactor to shut down,
175
    /// or a [`BackwardCellDisposition`] specifying how it should be handled.
176
    fn handle_backward_cell(
177
        &mut self,
178
        circ_uniq_id: UniqId,
179
        circ_id: CircId,
180
        cell: Self::CircChanMsg,
181
    ) -> StdResult<BackwardCellDisposition, ReactorError>;
182
}
183

            
184
/// What action to take in response to a cell arriving on our outbound Tor channel.
185
pub(crate) enum BackwardCellDisposition {
186
    /// Forward the cell, writing it to the inbound Tor channel.
187
    Forward(AnyChanMsg),
188
}
189

            
190
#[allow(unused)] // TODO(relay)
191
impl<B: BackwardHandler> BackwardReactor<B> {
192
    /// Create a new [`BackwardReactor`].
193
    #[allow(clippy::too_many_arguments)] // TODO
194
58
    pub(super) fn new<R: Runtime>(
195
58
        runtime: R,
196
58
        channel: &Arc<Channel>,
197
58
        circ_id: CircId,
198
58
        unique_id: UniqId,
199
58
        inner: B,
200
58
        hops: Arc<RwLock<CircHopList>>,
201
58
        forward_reactor_rx: mpsc::Receiver<BackwardReactorCmd>,
202
58
        control_rx: mpsc::UnboundedReceiver<CtrlMsg<B::CtrlMsg>>,
203
58
        command_rx: mpsc::UnboundedReceiver<CtrlCmd<B::CtrlCmd>>,
204
58
        padding_ctrl: PaddingController,
205
58
        padding_event_stream: PaddingEventStream,
206
58
        stream_rx: mpsc::Receiver<ReadyStreamMsg>,
207
58
    ) -> Self {
208
58
        let channel = Arc::clone(channel);
209
58
        let inbound_chan_tx = CircuitCellSender::from_channel_sender(channel.sender());
210

            
211
58
        Self {
212
58
            time_provider: DynTimeProvider::new(runtime),
213
58
            outbound_chan_rx: None,
214
58
            channel,
215
58
            inner,
216
58
            hops,
217
58
            inbound_chan_tx,
218
58
            unique_id,
219
58
            circ_id,
220
58
            forward_reactor_rx,
221
58
            control_rx,
222
58
            command_rx,
223
58
            stream_rx,
224
58
            padding_ctrl,
225
58
            padding_event_stream,
226
58
            #[cfg(feature = "circ-padding")]
227
58
            padding_block: None,
228
58
        }
229
58
    }
230

            
231
    /// Helper for [`run`](Self::run).
232
    ///
233
    /// Handles cells arriving on the outbound Tor channel,
234
    /// and writes cells to the inbound Tor channel.
235
    ///
236
    /// Because the Tor application streams, the `forward_reactor_rx` MPSC streams,
237
    /// and the outbound Tor channel MPSC stream are driven concurrently using [`PollAll`],
238
    /// this function can send up to 3 cells per call over the inbound Tor channel:
239
    ///
240
    ///    * a cell carrying Tor stream data
241
    ///    * a cell received from the outbound Tor channel, if we are a relay
242
    ///      (moving from the exit towards the client)
243
    ///    * a circuit-level SENDME
244
    ///
245
    /// However, in practice, leaky pipe is not really used,
246
    /// and so relays that have application streams (i.e. the exits),
247
    /// are not going to have an outbound Tor channel,
248
    /// and so this will only really drive Tor stream data,
249
    /// delivering at most 2 cells per call.
250
78
    async fn run_once(&mut self) -> StdResult<(), ReactorError> {
251
        use postage::prelude::{Sink as _, Stream as _};
252

            
253
        /// The maximum number of events we expect to handle per reactor loop.
254
        ///
255
        /// This is bounded by the number of futures we push into the PollAll.
256
        const PER_LOOP_EVENT_COUNT: usize = 3;
257

            
258
        // A collection of futures we plan to drive concurrently.
259
78
        let mut poll_all =
260
78
            PollAll::<PER_LOOP_EVENT_COUNT, Option<CircuitEvent<B::CircChanMsg>>>::new();
261

            
262
        // Flush the backward Tor channel sink, and check it for readiness
263
        //
264
        // TODO(flushing): here and everywhere else we need to flush:
265
        //
266
        // Currently, we try to flush every time we want to write to the sink,
267
        // but may be suboptimal.
268
        //
269
        // However, we don't actually *wait* for the flush to complete
270
        // (we just make a bit of progress by calling poll_flush),
271
        // so it's possible that this is actually tolerable.
272
        // We should run some tests, and if this turns out to be a performance bottleneck,
273
        // we'll have to rethink our flushing approach.
274
78
        let backward_chan_ready = future::poll_fn(|cx| {
275
            // The flush outcome doesn't matter,
276
            // so we simply move on to the readiness check.
277
            // The reason we don't wait on the flush is because we don't
278
            // want to flush on *every* reactor loop, but we do want to make
279
            // a bit of progress each time.
280
            //
281
            // (TODO: do we want to handle errors here?)
282
78
            let _ = self.inbound_chan_tx.poll_flush_unpin(cx);
283

            
284
78
            self.inbound_chan_tx.poll_ready_unpin(cx)
285
78
        });
286

            
287
        // Concurrently, drive :
288
        //  1. a future that reads from the StreamReactor, to see if there are
289
        //  any application streams that have a message to send
290
        //  (this resolves to a message that needs to be delivered to the peer)
291
78
        poll_all.push(async {
292
            // Internally, each stream reactor checks if we're allowed to send anything
293
            // that counts towards SENDME windows (and ceases to send us stream data if not)
294
            //
295
            // The reason we don't check that here is because stream_rx multiplexes stream data
296
            // from all hops, and we have no way of knowing which hop will want to send us stream
297
            // data next, and therefore we can't know which hop's CC object to use
298
78
            self.stream_rx.next().await.map(CircuitEvent::Send)
299
8
        });
300

            
301
        //  2. the stream of commands coming from the ForwardReactor
302
        //  (this resolves to a BackwardReactorCmd)
303
78
        poll_all.push(async {
304
78
            let event = match self.forward_reactor_rx.next().await {
305
12
                Some(cmd) => CircuitEvent::Forwarded(cmd),
306
                None => {
307
                    // The forward reactor has crashed, so we have to shut down.
308
                    CircuitEvent::ForwardShutdown
309
                }
310
            };
311

            
312
12
            Some(event)
313
12
        });
314

            
315
        // 3. Messages moving from the outbound channel towards the inbound Tor channel,
316
        // if we have an outbound Tor channel.
317
        //
318
        // NOTE: in practice, clients and exits won't have an outbound Tor channel,
319
        // so for them this will be a no-op.
320
78
        poll_all.push(async {
321
78
            let event = if let Some(outbound_chan_rx) = self.outbound_chan_rx.as_mut() {
322
                // Forward channel unexpectedly closed, we should close too
323
12
                match outbound_chan_rx.next().await {
324
4
                    Some(msg) => match msg.try_into() {
325
                        Err(e) => CircuitEvent::ProtoViolation(e),
326
4
                        Ok(cell) => CircuitEvent::Cell(cell),
327
                    },
328
                    None => {
329
                        // The forward reactor has crashed, so we have to shut down.
330
                        CircuitEvent::ForwardShutdown
331
                    }
332
                }
333
            } else {
334
66
                future::pending().await
335
            };
336

            
337
4
            Some(event)
338
4
        });
339

            
340
78
        let poll_all = async move {
341
            // Avoid polling **any** of the futures if the outgoing sink is blocked.
342
            //
343
            // This implements backpressure: we avoid reading from our input sources
344
            // if we know we're unable to write to the inbound Tor channel sink.
345
            //
346
            // More specifically, if our inbound Tor channel sink is full and can no longer
347
            // accept cells, we stop reading:
348
            //
349
            //   1. From the application streams (received from StreamReactor), if there are any.
350
            //
351
            //   2. From the forward_reactor_rx channel, used by the forward reactor to send us
352
            //
353
            //     - a circuit-level SENDME that we have received, or
354
            //     - a circuit-level SENDME that we need to deliver to the client
355
            //
356
            //     Not reading from the forward_reactor_rx channel, in turn, causes the forward reactor
357
            //     to block and therefore stop reading from **its** input sources,
358
            //     propagating backpressure all the way to the other endpoint of the circuit.
359
            //
360
            //   3. From the outbound Tor channel, if there is one.
361
            //
362
            // This will delay any SENDMEs the client or exit might have sent along
363
            // the way, and therefore count as a congestion signal.
364
            //
365
            // TODO: memquota setup to make sure this doesn't turn into a memory DOS vector
366
78
            let _ = backward_chan_ready.await;
367

            
368
            // TODO: it's important to not block reading from the forward_reactor_rx channel on the chan
369
            // sender readiness (for instance, we should not block the sending of SENDMEs
370
            // if the channel is blocked on a padding-induced block).
371
            //
372
            // This means we will need to move the forward_reactor_rx handling out of the PollAll
373
            // to the select_biased! below.
374
78
            poll_all.await
375
24
        };
376

            
377
78
        let events = select_biased! {
378
78
            res = self.command_rx.next().fuse() => {
379
                let cmd = res.ok_or_else(|| ReactorError::Shutdown)?;
380
                self.handle_cmd(cmd)?;
381
                return Ok(());
382
            }
383
78
            res = self.control_rx.next().fuse() => {
384
                let msg = res.ok_or_else(|| ReactorError::Shutdown)?;
385
                self.handle_msg(msg)?;
386
                return Ok(());
387
            }
388
78
            res = self.padding_event_stream.next().fuse() => {
389
                // If there's a padding event, we need to handle it immediately,
390
                // because it might tell us to start blocking the inbound_chan_tx sink,
391
                // which, in turn, means we need to stop trying to read from
392
                // the application streams.
393
                let event = res.ok_or_else(|| ReactorError::Shutdown)?;
394

            
395
                cfg_if::cfg_if! {
396
                    if #[cfg(feature = "circ-padding")] {
397
                        self.run_padding_event(event).await?;
398
                    } else {
399
                        // If padding isn't enabled, we never generate a padding event,
400
                        // so we can be sure this case will never be called.
401
                        void::unreachable(event.0);
402
                    }
403
                }
404
                return Ok(())
405
            }
406
78
            res = poll_all.fuse() => res,
407
        };
408

            
409
        // Note: there shouldn't be more than N < PER_LOOP_EVENT_COUNT events to handle
410
        // per reactor loop. We need to be careful here, because we must avoid blocking
411
        // the reactor.
412
        //
413
        // If handling more than one event per loop turns out to be a problem, we may
414
        // need to dispatch this to a background task instead.
415
        //
416
        // TODO(relay): this loop is actually a problem.
417
        // As mentioned in the run_once() docs, this will attempt to send up
418
        // to 3 cells on the inbound tor Channel (or 2 cells, assuming no leaky pipe).
419
        //
420
        // The problem is that the readiness check above (see backward_chan_ready)
421
        // only checks that the queue has enough room for 1 cell, not *2 cells*.
422
        // Trying to send more than 2 cell when there is only room for one
423
        // will cause the reactor to block (and because there is nothing
424
        // driving the flushing of this channel, this will be a hard block).
425
        //
426
        // We need to rethink the strategy here (e.g. by flushing in parallel
427
        // with handle_event())
428
24
        for event in events.into_iter().flatten() {
429
24
            self.handle_event(event).await?;
430
        }
431

            
432
20
        Ok(())
433
24
    }
434

            
435
    /// Handle a control command.
436
    fn handle_cmd(&mut self, cmd: CtrlCmd<B::CtrlCmd>) -> StdResult<(), ReactorError> {
437
        match cmd {
438
            CtrlCmd::Custom(c) => self.inner.handle_cmd(c),
439
        }
440
    }
441

            
442
    /// Handle a control message.
443
    fn handle_msg(&mut self, msg: CtrlMsg<B::CtrlMsg>) -> StdResult<(), ReactorError> {
444
        match msg {
445
            CtrlMsg::Custom(c) => self.inner.handle_msg(c),
446
        }
447
    }
448

            
449
    /// Perform some circuit-padding-based event on the specified circuit.
450
    //
451
    // TODO(DEDUP): this is almost identical to the client-side Conflux::run_padding_event()
452
    #[cfg(feature = "circ-padding")]
453
    async fn run_padding_event(
454
        &mut self,
455
        padding_event: PaddingEvent,
456
    ) -> StdResult<(), ReactorError> {
457
        use PaddingEvent as E;
458

            
459
        match padding_event {
460
            E::SendPadding(send_padding) => {
461
                self.send_padding(send_padding).await?;
462
            }
463
            E::StartBlocking(start_blocking) => {
464
                self.start_blocking_for_padding(start_blocking);
465
            }
466
            E::StopBlocking => {
467
                self.stop_blocking_for_padding();
468
            }
469
        }
470
        Ok(())
471
    }
472

            
473
    /// Handle a request from our padding subsystem to send a padding packet.
474
    //
475
    // TODO(DEDUP): this is almost identical to the client-side Client::send_padding()
476
    #[cfg(feature = "circ-padding")]
477
    async fn send_padding(&mut self, send_padding: padding::SendPadding) -> Result<()> {
478
        use CircPaddingDisposition::*;
479

            
480
        let target_hop = send_padding.hop;
481

            
482
        match padding_disposition(
483
            &send_padding,
484
            &self.inbound_chan_tx,
485
            self.padding_block.as_ref(),
486
        ) {
487
            QueuePaddingNormally => {
488
                let queue_info = self.padding_ctrl.queued_padding(target_hop, send_padding);
489
                self.queue_padding_cell_for_hop(target_hop, queue_info)
490
                    .await?;
491
            }
492
            QueuePaddingAndBypass => {
493
                let queue_info = self.padding_ctrl.queued_padding(target_hop, send_padding);
494
                self.queue_padding_cell_for_hop(target_hop, queue_info)
495
                    .await?;
496
            }
497
            TreatQueuedCellAsPadding => {
498
                self.padding_ctrl
499
                    .replaceable_padding_already_queued(target_hop, send_padding);
500
            }
501
        }
502
        Ok(())
503
    }
504

            
505
    /// Enable padding-based blocking,
506
    /// or change the rule for padding-based blocking to the one in `block`.
507
    //
508
    // TODO(DEDUP): copy of Client::start_blocking_for_padding()
509
    #[cfg(feature = "circ-padding")]
510
    pub(super) fn start_blocking_for_padding(&mut self, block: padding::StartBlocking) {
511
        self.inbound_chan_tx.start_blocking();
512
        self.padding_block = Some(block);
513
    }
514

            
515
    /// Disable padding-based blocking.
516
    ///
517
    // TODO(DEDUP): copy of Client::stop_blocking_for_padding()
518
    #[cfg(feature = "circ-padding")]
519
    pub(super) fn stop_blocking_for_padding(&mut self) {
520
        self.inbound_chan_tx.stop_blocking();
521
        self.padding_block = None;
522
    }
523

            
524
    /// Generate and encrypt a padding cell, and send it to a targeted hop.
525
    ///
526
    /// Ignores any padding-based blocking.
527
    ///
528
    // TODO(DEDUP): copy of Client::queue_padding_cell_for_hop()
529
    #[cfg(feature = "circ-padding")]
530
    async fn queue_padding_cell_for_hop(
531
        &mut self,
532
        target_hop: HopNum,
533
        queue_info: Option<QueuedCellPaddingInfo>,
534
    ) -> Result<()> {
535
        use tor_cell::relaycell::msg::Drop as DropMsg;
536

            
537
        let msg = AnyRelayMsgOuter::new(None, DropMsg::default().into());
538
        let hopnum = Some(target_hop);
539

            
540
        // TODO: the ccontrol state isn't actually needed here, because
541
        // DROP cells don't count towards SENDME windows.
542
        // Technically, we could avoid unnecessarily Arc::clone()ing the CC state
543
        // here, and just extract the relay cell format.
544
        // But for that we would need a specialized send_relay_cell_inner()-like function
545
        // that doesn't take a CC object, or to make the CC object optional in
546
        // send_relay_cell_inner().
547
        let (relay_cell_format, ccontrol) = self.hop_info(hopnum)?;
548

            
549
        self.send_relay_cell_inner(hopnum, relay_cell_format, msg, false, &ccontrol, queue_info)
550
            .await
551
    }
552

            
553
    /// Determine how exactly to handle a request to handle padding.
554
    #[cfg(feature = "circ-padding")]
555
    fn padding_disposition(&self, send_padding: &padding::SendPadding) -> CircPaddingDisposition {
556
        crate::circuit::padding::padding_disposition(
557
            send_padding,
558
            &self.inbound_chan_tx,
559
            self.padding_block.as_ref(),
560
        )
561
    }
562

            
563
    /// Handle a circuit event.
564
24
    async fn handle_event(
565
24
        &mut self,
566
24
        event: CircuitEvent<B::CircChanMsg>,
567
24
    ) -> StdResult<(), ReactorError> {
568
        use CircuitEvent::*;
569

            
570
24
        match event {
571
4
            Cell(cell) => self.handle_backward_cell(cell).await,
572
8
            Send(msg) => {
573
                let ReadyStreamMsg {
574
8
                    hop,
575
8
                    relay_cell_format,
576
8
                    msg,
577
8
                    ccontrol,
578
8
                } = msg;
579

            
580
8
                self.send_relay_cell(hop, relay_cell_format, msg, false, &ccontrol)
581
8
                    .await?;
582

            
583
8
                Ok(())
584
            }
585
12
            Forwarded(cmd) => self.handle_reactor_cmd(cmd).await,
586
            ForwardShutdown => {
587
                // The forward reactor has crashed, so we have to shut down.
588
                trace!(
589
                    circ_uniq_id = %self.unique_id,
590
                    backward_circ_id = %self.circ_id,
591
                    "Backward relay reactor shutdown (forward reactor has closed)",
592
                );
593

            
594
                Err(ReactorError::Shutdown)
595
            }
596
            ProtoViolation(err) => Err(err.into()),
597
        }
598
24
    }
599

            
600
    /// Return the RelayCellFormat and CC state of a given hop.
601
12
    fn hop_info(
602
12
        &self,
603
12
        hopnum: Option<HopNum>,
604
12
    ) -> Result<(RelayCellFormat, Arc<Mutex<CongestionControl>>)> {
605
12
        let hops = self.hops.read().expect("poisoned lock");
606
12
        let hop = hops
607
12
            .get(hopnum)
608
12
            .ok_or_else(|| internal!("tried to send padding to non-existent hop?!"))?;
609
12
        let relay_cell_format = hop.settings.relay_crypt_protocol().relay_cell_format();
610
12
        let ccontrol = Arc::clone(&hop.ccontrol);
611

            
612
12
        Ok((relay_cell_format, ccontrol))
613
12
    }
614

            
615
    /// Handle a command sent to us by the forward reactor.
616
12
    async fn handle_reactor_cmd(&mut self, msg: BackwardReactorCmd) -> StdResult<(), ReactorError> {
617
        use BackwardReactorCmd::*;
618

            
619
12
        match msg {
620
            SendRelayMsg { hop, msg } => {
621
                self.send_relay_msg(hop, msg).await?;
622
            }
623
            HandleSendme { hop, sendme } => {
624
                self.handle_sendme(hop, sendme).await?;
625
                return Ok(());
626
            }
627
            #[cfg(feature = "relay")]
628
            HandleCircuitExtended {
629
12
                hop,
630
12
                extended2,
631
12
                outbound_chan_rx,
632
            } => {
633
12
                self.outbound_chan_rx = Some(outbound_chan_rx);
634
12
                let msg = AnyRelayMsgOuter::new(None, extended2.into());
635
12
                self.send_relay_msg(hop, msg).await?;
636

            
637
12
                debug!(
638
                    circ_uniq_id = %self.unique_id,
639
                    backward_circ_id = %self.circ_id,
640
                    "Extended circuit to the next hop"
641
                );
642
            }
643
        }
644

            
645
12
        Ok(())
646
12
    }
647

            
648
    /// Send a relay message to the specified hop.
649
12
    async fn send_relay_msg(
650
12
        &mut self,
651
12
        hopnum: Option<HopNum>,
652
12
        msg: AnyRelayMsgOuter,
653
12
    ) -> StdResult<(), ReactorError> {
654
12
        let (relay_cell_format, ccontrol) = self.hop_info(hopnum)?;
655
12
        let cmd = msg.cmd();
656

            
657
        // TODO(relay): remove this log once we add some tests
658
        // and confirm relaying cells works as expected
659
        // (in practice it will be too noisy to be useful, even at trace level).
660
12
        trace!(
661
            circ_uniq_id = %self.unique_id,
662
            backward_circ_id = %self.circ_id,
663
            hopnum=?hopnum,
664
            cmd = %cmd,
665
            "Sending backward cell"
666
        );
667

            
668
12
        self.send_relay_cell(hopnum, relay_cell_format, msg, false, &ccontrol)
669
12
            .await?;
670

            
671
12
        if cmd == RelayCmd::SENDME {
672
            ccontrol.lock().expect("poisoned lock").note_sendme_sent();
673
12
        }
674

            
675
12
        Ok(())
676
12
    }
677

            
678
    /// Handle a circuit-level SENDME (stream ID = 0).
679
    ///
680
    /// Returns an error if the SENDME does not have an authentication tag
681
    /// (versions of Tor <=0.3.5 omit the SENDME tag, but we don't support
682
    /// those any longer).
683
    ///
684
    /// Any error returned from this function will shut down the reactor.
685
    ///
686
    // TODO(DEDUP): duplicates the logic from the client-side Circuit::handle_sendme()
687
    async fn handle_sendme(
688
        &mut self,
689
        hopnum: Option<HopNum>,
690
        sendme: Sendme,
691
    ) -> StdResult<(), ReactorError> {
692
        let tag = sendme
693
            .into_sendme_tag()
694
            .ok_or_else(|| Error::CircProto("missing tag on circuit sendme".into()))?;
695

            
696
        // NOTE: it's okay to await. We are only awaiting on the congestion_signals
697
        // future which *should* resolve immediately
698
        let signals = self.inbound_chan_tx.congestion_signals().await;
699

            
700
        let hops = self.hops.read().expect("poisoned lock");
701
        let hop = hops
702
            .get(hopnum)
703
            .ok_or_else(|| internal!("tried to send padding to non-existent hop?!"))?;
704

            
705
        // Update the CC object that we received a SENDME along
706
        // with possible congestion signals.
707
        hop.ccontrol
708
            .lock()
709
            .expect("poisoned lock")
710
            .note_sendme_received(&self.time_provider, tag, signals)?;
711

            
712
        Ok(())
713
    }
714

            
715
    /// Encode `msg` and encrypt it, returning the resulting cell
716
    /// and tag that should be expected for an authenticated SENDME sent
717
    /// in response to that cell.
718
    ///
719
    // TODO(DEDUP): duplicates the logic from the client-side Circuit::encode_relay_cell()
720
20
    fn encode_relay_cell(
721
20
        &mut self,
722
20
        relay_format: RelayCellFormat,
723
20
        hop: Option<HopNum>,
724
20
        early: bool,
725
20
        msg: AnyRelayMsgOuter,
726
20
    ) -> Result<(AnyChanMsg, SendmeTag)> {
727
20
        let mut body: RelayCellBody = msg
728
20
            .encode(relay_format, &mut rand::rng())
729
20
            .map_err(|e| Error::from_cell_enc(e, "relay cell body"))?
730
20
            .into();
731
20
        let cmd = if early {
732
            ChanCmd::RELAY_EARLY
733
        } else {
734
20
            ChanCmd::RELAY
735
        };
736

            
737
        // Use the implementation-dependent encryption logic
738
20
        let tag = self.inner.encrypt_relay_cell(cmd, &mut body, hop);
739
20
        let msg = Relay::from(BoxedCellBody::from(body));
740
20
        let msg = if early {
741
            AnyChanMsg::RelayEarly(msg.into())
742
        } else {
743
20
            AnyChanMsg::Relay(msg)
744
        };
745

            
746
20
        Ok((msg, tag))
747
20
    }
748

            
749
    /// Encode `msg`, encrypt it, and send it to the 'hop'th hop.
750
    ///
751
    /// If there is insufficient outgoing *circuit-level* or *stream-level*
752
    /// SENDME window, an error is returned instead.
753
    ///
754
    /// Does not check whether the cell is well-formed or reasonable.
755
20
    async fn send_relay_cell(
756
20
        &mut self,
757
20
        hop: Option<HopNum>,
758
20
        relay_cell_format: RelayCellFormat,
759
20
        msg: AnyRelayMsgOuter,
760
20
        early: bool,
761
20
        ccontrol: &Arc<Mutex<CongestionControl>>,
762
20
    ) -> Result<()> {
763
20
        self.send_relay_cell_inner(hop, relay_cell_format, msg, early, ccontrol, None)
764
20
            .await
765
20
    }
766

            
767
    /// As [`send_relay_cell`](Self::send_relay_cell), but takes an optional
768
    /// [`QueuedCellPaddingInfo`] in `padding_info`.
769
    ///
770
    /// If `padding_info` is None, `msg` must be non-padding: we report it as such to the
771
    /// padding controller.
772
    ///
773
    // TODO(DEDUP): this contains parts of Circuit::send_relay_cell_inner()
774
20
    async fn send_relay_cell_inner(
775
20
        &mut self,
776
20
        hop: Option<HopNum>,
777
20
        relay_cell_format: RelayCellFormat,
778
20
        msg: AnyRelayMsgOuter,
779
20
        early: bool,
780
20
        ccontrol: &Arc<Mutex<CongestionControl>>,
781
20
        padding_info: Option<QueuedCellPaddingInfo>,
782
20
    ) -> Result<()> {
783
20
        let c_t_w = sendme::cmd_counts_towards_windows(msg.cmd());
784
20
        let (msg, tag) = self.encode_relay_cell(relay_cell_format, hop, early, msg)?;
785
20
        let cell = AnyChanCell::new(Some(self.circ_id), msg);
786

            
787
        // TODO: we use HopNum(0) if we're a relay (i.e. if the hop is None).
788
        // Is that ok?
789
20
        let hop = hop.unwrap_or_else(|| HopNum::from(0));
790
        // Remember that we've enqueued this cell.
791
20
        let padding_info = padding_info.or_else(|| self.padding_ctrl.queued_data(hop));
792

            
793
        // Note: this future is always `Ready`, because we checked the sink for readiness
794
        // before polling the async streams, so await won't block.
795
20
        Pin::new(&mut self.inbound_chan_tx)
796
20
            .send_unbounded((cell, padding_info))
797
20
            .await?;
798

            
799
20
        if c_t_w {
800
            ccontrol
801
                .lock()
802
                .expect("poisoned lock")
803
                .note_data_sent(&self.time_provider, &tag)?;
804
20
        }
805

            
806
20
        Ok(())
807
20
    }
808

            
809
    /// Handle a backward cell (moving from the exit towards the client).
810
4
    async fn handle_backward_cell(&mut self, cell: B::CircChanMsg) -> StdResult<(), ReactorError> {
811
4
        match self
812
4
            .inner
813
4
            .handle_backward_cell(self.unique_id, self.circ_id, cell)?
814
        {
815
            BackwardCellDisposition::Forward(cell) => {
816
                let cell = AnyChanCell::new(Some(self.circ_id), cell);
817
                self.inbound_chan_tx
818
                    .send((cell, None))
819
                    .await
820
                    .map_err(ReactorError::Err)
821
            }
822
        }
823
4
    }
824
}
825

            
826
impl<B: BackwardHandler> Drop for BackwardReactor<B> {
827
58
    fn drop(&mut self) {
828
        // This will send a DESTROY down the inbound Tor channel
829
58
        let _ = self.channel.close_circuit(self.circ_id);
830
58
    }
831
}
832

            
833
/// A circuit event that must be handled by the [`BackwardReactor`].
834
enum CircuitEvent<M> {
835
    /// We received a cell that needs to be handled.
836
    ///
837
    /// The cell is client-bound if we are a relay, or exit-bound if we are a client).
838
    Cell(M),
839
    /// We received a RELAY cell from the stream reactor that needs
840
    /// to be packaged and written to our Tor channel.
841
    ///
842
    /// The message is client-bound if we are a relay, or exit-bound if we are a client).
843
    Send(ReadyStreamMsg),
844
    /// We received a cell from the ForwardReactor that we need to handle.
845
    ///
846
    /// This might be
847
    ///
848
    ///   * a circuit-level SENDME that we have received, or
849
    ///   * a circuit-level SENDME that we need to deliver to the client
850
    Forwarded(BackwardReactorCmd),
851
    /// The forward reactor has shut down.
852
    ///
853
    /// We need to shut down too.
854
    ForwardShutdown,
855
    /// Protocol violation.
856
    ///
857
    /// This can happen if we receive a channel message that is not supported on the channel.
858
    ProtoViolation(Error),
859
}
860

            
861
/// Instructions from the forward reactor.
862
pub(crate) enum BackwardReactorCmd {
863
    /// A circuit SENDME we received from the other endpoint.
864
    HandleSendme {
865
        /// The hop the SENDME came on.
866
        hop: Option<HopNum>,
867
        /// The SENDME.
868
        sendme: Sendme,
869
    },
870
    /// A message we need to send back to the other endpoint.
871
    SendRelayMsg {
872
        /// The hop to encode the message for.
873
        hop: Option<HopNum>,
874
        /// The message to send.
875
        msg: AnyRelayMsgOuter,
876
    },
877
    /// This relay circuit was extended by another hop.
878
    ///
879
    /// This causes the reactor send the `extended2` message on its inbound channel,
880
    /// and start reading from `outbound_chan_rx` in the main loop.
881
    //
882
    ///
883
    // TODO: I wish we didn't need to expose this relay-specific variant
884
    // in the generic reactor but we have no choice: abstracting it away
885
    // means either introducing a mutex between the relay-side forward/backward
886
    // handlers, or yet another mpsc between them.
887
    #[cfg(feature = "relay")]
888
    HandleCircuitExtended {
889
        /// The hop to encode the message for.
890
        ///
891
        /// In practice, this is always None, because only relays use this.
892
        hop: Option<HopNum>,
893
        /// The cell to send to the specified hop,
894
        extended2: Extended2,
895
        /// The reading end of the outbound Tor channel, if we are not the last hop.
896
        ///
897
        /// Yields cells moving from the exit towards the client, if we are a middle relay.
898
        outbound_chan_rx: CircuitRxReceiver,
899
    },
900
}