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>;