pub(crate) mod channel;
#[allow(unreachable_pub)] pub mod channel_provider;
pub(crate) mod reactor;
pub use channel::MaybeVerifiableRelayResponderChannel;
pub use channel::create_handler::{
CircNetParameters, CongestionControlNetParams, CreateRequestHandler,
IncomingStreamRequestFilterFactory,
};
use derive_deftly::Deftly;
use oneshot_fused_workaround as oneshot;
use tor_cell::chancell::msg::{self as chanmsg};
use tor_cell::relaycell::StreamId;
use tor_cell::relaycell::flow_ctrl::XonKbpsEwma;
use tor_memquota::derive_deftly_template_HasMemoryCost;
use crate::Error;
use crate::circuit::celltypes::derive_deftly_template_RestrictedChanMsgSet;
use crate::circuit::reactor::CircReactorHandle;
use crate::circuit::reactor::CtrlCmd;
use crate::circuit::reactor::forward;
use crate::relay::reactor::backward::Backward;
use crate::relay::reactor::forward::Forward;
use crate::stream::incoming::IncomingStreamRequestFilter;
#[derive(Debug, Deftly)]
#[derive_deftly(HasMemoryCost)]
#[derive_deftly(RestrictedChanMsgSet)]
#[deftly(usage = "on an open relay circuit")]
#[cfg(feature = "relay")]
#[cfg_attr(not(test), allow(unused))] pub(crate) enum RelayCircChanMsg {
Relay(chanmsg::Relay),
RelayEarly(chanmsg::RelayEarly),
Destroy(chanmsg::Destroy),
PaddingNegotiate(chanmsg::PaddingNegotiate),
}
#[allow(unused)] #[derive(Debug)]
pub struct RelayCirc(pub(crate) CircReactorHandle<Forward, Backward>);
impl RelayCirc {
pub fn terminate(&self) {
let _ = self.0.command.unbounded_send(CtrlCmd::Shutdown);
}
pub fn is_closing(&self) -> bool {
self.0.control.is_closed()
}
pub(crate) fn drain_rate_update(
&self,
_stream_id: StreamId,
_rate: XonKbpsEwma,
) -> crate::Result<()> {
todo!()
}
pub(crate) fn send_sendme(&self, _stream_id: StreamId) -> crate::Result<()> {
todo!()
}
pub(crate) fn close_pending(
&self,
stream_id: StreamId,
message: crate::stream::CloseStreamBehavior,
) -> crate::Result<oneshot::Receiver<crate::Result<()>>> {
let (tx, rx) = oneshot::channel();
let cmd = forward::CtrlCmd::ClosePendingStream {
stream_id,
hop: None,
message,
done: tx,
};
self.0
.command
.unbounded_send(CtrlCmd::Forward(cmd))
.map_err(|_| Error::CircuitClosed)?;
Ok(rx)
}
}
#[cfg(test)]
mod test {
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::dbg_macro)]
#![allow(clippy::mixed_attributes_style)]
#![allow(clippy::print_stderr)]
#![allow(clippy::print_stdout)]
#![allow(clippy::single_char_pattern)]
#![allow(clippy::unwrap_used)]
#![allow(clippy::unchecked_time_subtraction)]
#![allow(clippy::useless_vec)]
#![allow(clippy::needless_pass_by_value)]
#![allow(clippy::string_slice)]
#[test]
fn relay_circ_chan_msg() {
use tor_cell::chancell::msg::{self, AnyChanMsg};
fn good(m: AnyChanMsg) {
use crate::relay::RelayCircChanMsg;
assert!(RelayCircChanMsg::try_from(m).is_ok());
}
fn bad(m: AnyChanMsg) {
use crate::relay::RelayCircChanMsg;
assert!(RelayCircChanMsg::try_from(m).is_err());
}
good(msg::Destroy::new(2.into()).into());
bad(msg::CreatedFast::new(&b"The great globular mass"[..]).into());
bad(msg::Created2::new(&b"of protoplasmic slush"[..]).into());
good(msg::Relay::new(&b"undulated slightly,"[..]).into());
good(msg::AnyChanMsg::RelayEarly(
msg::Relay::new(&b"as if aware of him"[..]).into(),
));
bad(msg::Versions::new([1, 2, 3]).unwrap().into());
good(msg::PaddingNegotiate::start_default().into());
good(msg::RelayEarly::from(msg::Relay::new(b"snail-like unipedular organism")).into());
}
}