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