tor_proto/stream/
cmdcheck.rs

1//! Declare a "command checker" trait that checks whether a given relay message
2//! is acceptable on a given stream.
3
4use tor_cell::relaycell::UnparsedRelayMsg;
5
6use crate::Result;
7
8/// A value returned by CmdChecker on success.
9#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10pub(crate) enum StreamStatus {
11    /// The stream is still open.
12    Open,
13    /// The stream has been closed successfully; any further messages received
14    /// on this stream would be a protocol violation, which should cause
15    /// us to close the circuit.
16    Closed,
17}
18
19/// An object that checks incoming commands before they are sent to a stream.
20///
21/// These checks are called from the circuit reactor code, which runs in its own
22/// task. The reactor code continues calling these checks we have sent our own
23/// END cell on the stream.  See `crate::tunnel::circuit::halfstream` for more
24/// information.
25///
26/// NOTE: The checking DOES NOT take SENDME messages into account; those are
27/// handled separately.  Neither of the methods on this trait will ever be
28/// passed a SENDME message.
29///
30/// See [`circuit::reactor`](crate::tunnel::reactor) for more information on
31/// how these checks relate to other checks performed on incoming messages.
32pub(crate) trait CmdChecker: std::fmt::Debug {
33    /// Look at a message `msg` and decide whether it can be handled on this
34    /// stream.
35    ///
36    /// If `msg` is invalid, return an error, indicating that the protocol has
37    /// been violated and the corresponding circuit should be closed.
38    ///
39    /// If `msg` is invalid, update the state of this checker, and return a
40    /// `StreamStatus` indicating whether the last message closed.
41    fn check_msg(&mut self, msg: &UnparsedRelayMsg) -> Result<StreamStatus>;
42
43    /// Consume `msg` and make sure it can be parsed correctly.
44    ///
45    /// This is an additional check, beyond check_msg(), performed for half-open
46    /// streams.  It should only be called  if check_msg() succeeds.  It shouldn't
47    /// be called on open streams: for those, the stream itself parses the message
48    /// and consumes it.
49    fn consume_checked_msg(&mut self, msg: UnparsedRelayMsg) -> Result<()>;
50}
51
52/// Type alias for a CmdChecker of unspecified type.
53//
54// TODO: Someday we might turn this into an enum if we decide it's beneficial.
55pub(crate) type AnyCmdChecker = Box<dyn CmdChecker + Send + 'static>;