pub(crate) mod cell_sender;
pub(crate) mod celltypes;
pub(crate) mod circ_sender;
pub(crate) mod circhop;
pub(crate) mod create;
pub(crate) mod padding;
pub(crate) mod reactor;
pub(crate) mod syncview;
pub(crate) mod unique_id;
pub use crate::memquota::StreamAccount;
pub use syncview::CircHopSyncView;
pub use unique_id::UniqId;
use crate::ccparams::CongestionControlParams;
use crate::stream::flow_ctrl::params::FlowCtrlParameters;
use tor_cell::relaycell::extend::SubprotocolRequest;
use tor_error::ErrorKind;
use tor_protover::Protocols;
pub(crate) use circ_sender::{CircuitRxReceiver, CircuitRxSender};
pub(crate) const HOPS: usize = 6;
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct CircParameters {
pub extend_by_ed25519_id: bool,
pub ccontrol: CongestionControlParams,
pub flow_ctrl: FlowCtrlParameters,
pub n_incoming_cells_permitted: Option<u32>,
pub n_outgoing_cells_permitted: Option<u32>,
}
tor_protover::subprotocol_restricted_set! {
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub(crate) struct HandshakeSubprotocols {
RELAY_CRYPT_CGO,
}
}
impl HandshakeSubprotocols {
pub(crate) fn try_from_request(
protos: SubprotocolRequest,
) -> Result<Self, InvalidHandshakeSubprotocolError> {
use std::sync::LazyLock;
static ALL: LazyLock<Protocols> =
LazyLock::new(|| Protocols::from(HandshakeSubprotocols::ALL));
if !protos.contains_only(&ALL) {
return Err(InvalidHandshakeSubprotocolError(protos));
}
Ok(Self {
relay_crypt_cgo: protos.contains(tor_protover::named::RELAY_CRYPT_CGO),
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
#[error("Request included subprotocols that we do not support in circuit handshakes: {0:?}")]
pub(crate) struct InvalidHandshakeSubprotocolError(SubprotocolRequest);
impl tor_error::HasKind for InvalidHandshakeSubprotocolError {
fn kind(&self) -> ErrorKind {
ErrorKind::TorProtocolViolation
}
}
#[cfg(test)]
pub(crate) mod test {
use super::*;
#[cfg(feature = "relay")]
use crate::relay::{CircNetParameters, CongestionControlNetParams};
pub(crate) use super::circ_sender::test::fake_mpsc;
#[cfg(feature = "relay")]
pub(crate) fn new_circ_net_params() -> CircNetParameters {
CircNetParameters {
cc: CongestionControlNetParams::defaults_for_tests(),
}
}
#[test]
fn handshake_subprotocols() {
let empty_iter: [tor_protover::NumberedSubver; 0] = [];
let request = SubprotocolRequest::from_iter(empty_iter);
assert_eq!(
HandshakeSubprotocols::try_from_request(request),
Ok(HandshakeSubprotocols {
relay_crypt_cgo: false,
}),
);
let request = SubprotocolRequest::from_iter([tor_protover::named::RELAY_CRYPT_CGO]);
assert_eq!(
HandshakeSubprotocols::try_from_request(request),
Ok(HandshakeSubprotocols {
relay_crypt_cgo: true,
}),
);
let request =
SubprotocolRequest::from_iter([tor_protover::named::RELAY_NEGOTIATE_SUBPROTO]);
assert!(HandshakeSubprotocols::try_from_request(request).is_err());
let request = SubprotocolRequest::from_iter([
tor_protover::named::RELAY_NEGOTIATE_SUBPROTO,
tor_protover::named::RELAY_CRYPT_CGO,
]);
assert!(HandshakeSubprotocols::try_from_request(request).is_err());
}
}