tor-cell: Use macro to generate ChanMsg too.
This commit is contained in:
parent
706a39a870
commit
71445f7ace
|
@ -1,3 +1,4 @@
|
|||
BREAKING: The interfaces for ChanMsg::Body and RelayMsg::Body have been made
|
||||
more uniform.
|
||||
BREAKING: RelayMsg no longer has any unit variants.
|
||||
BREAKING: RelayMsg no longer has any unit variants.
|
||||
BREAKING: Renamed VPadding to Vpadding, for consistent snake case.
|
||||
|
|
|
@ -24,133 +24,59 @@ pub trait Body: Readable {
|
|||
fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()>;
|
||||
}
|
||||
|
||||
crate::restrict::restricted_msg! {
|
||||
/// Decoded message from a channel.
|
||||
///
|
||||
/// A ChanMsg is an item received on a channel -- a message from
|
||||
/// another Tor client or relay that we are connected to directly over
|
||||
/// a TLS connection.
|
||||
#[non_exhaustive]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ChanMsg {
|
||||
#[non_exhaustive]
|
||||
pub enum ChanMsg : ChanMsg {
|
||||
/// A Padding message
|
||||
Padding(Padding),
|
||||
Padding,
|
||||
/// Variable-length padding message
|
||||
VPadding(VPadding),
|
||||
Vpadding,
|
||||
/// (Deprecated) TAP-based cell to create a new circuit.
|
||||
Create(Create),
|
||||
Create,
|
||||
/// (Mostly deprecated) HMAC-based cell to create a new circuit.
|
||||
CreateFast(CreateFast),
|
||||
CreateFast,
|
||||
/// Cell to create a new circuit
|
||||
Create2(Create2),
|
||||
Create2,
|
||||
/// (Deprecated) Answer to a Create cell
|
||||
Created(Created),
|
||||
Created,
|
||||
/// (Mostly Deprecated) Answer to a CreateFast cell
|
||||
CreatedFast(CreatedFast),
|
||||
CreatedFast,
|
||||
/// Answer to a Create2 cell
|
||||
Created2(Created2),
|
||||
Created2,
|
||||
/// A message sent along a circuit, likely to a more-distant relay.
|
||||
Relay(Relay),
|
||||
Relay,
|
||||
/// A message sent along a circuit (limited supply)
|
||||
RelayEarly(Relay),
|
||||
RelayEarly,
|
||||
/// Tear down a circuit
|
||||
Destroy(Destroy),
|
||||
Destroy,
|
||||
/// Part of channel negotiation: describes our position on the network
|
||||
Netinfo(Netinfo),
|
||||
Netinfo,
|
||||
/// Part of channel negotiation: describes what link protocol versions
|
||||
/// we support
|
||||
Versions(Versions),
|
||||
Versions,
|
||||
/// Negotiates what kind of channel padding to send
|
||||
PaddingNegotiate(PaddingNegotiate),
|
||||
PaddingNegotiate,
|
||||
/// Part of channel negotiation: additional certificates not in the
|
||||
/// TLS handshake
|
||||
Certs(Certs),
|
||||
Certs,
|
||||
/// Part of channel negotiation: additional random material to be used
|
||||
/// as part of authentication
|
||||
AuthChallenge(AuthChallenge),
|
||||
AuthChallenge,
|
||||
/// Part of channel negotiation: used to authenticate relays when they
|
||||
/// initiate the channel.
|
||||
Authenticate(Authenticate),
|
||||
Authenticate,
|
||||
/// Not yet used
|
||||
Authorize(Authorize),
|
||||
Authorize,
|
||||
_ =>
|
||||
/// Any cell whose command we don't recognize
|
||||
Unrecognized(Unrecognized),
|
||||
Unrecognized,
|
||||
}
|
||||
|
||||
impl super::ChanMsgClass for ChanMsg {
|
||||
fn cmd(&self) -> ChanCmd {
|
||||
use ChanMsg::*;
|
||||
match self {
|
||||
Padding(_) => ChanCmd::PADDING,
|
||||
VPadding(_) => ChanCmd::VPADDING,
|
||||
Create(_) => ChanCmd::CREATE,
|
||||
CreateFast(_) => ChanCmd::CREATE_FAST,
|
||||
Create2(_) => ChanCmd::CREATE2,
|
||||
Created(_) => ChanCmd::CREATED,
|
||||
CreatedFast(_) => ChanCmd::CREATED_FAST,
|
||||
Created2(_) => ChanCmd::CREATED2,
|
||||
Relay(_) => ChanCmd::RELAY,
|
||||
RelayEarly(_) => ChanCmd::RELAY_EARLY,
|
||||
Destroy(_) => ChanCmd::DESTROY,
|
||||
Netinfo(_) => ChanCmd::NETINFO,
|
||||
Versions(_) => ChanCmd::VERSIONS,
|
||||
PaddingNegotiate(_) => ChanCmd::PADDING_NEGOTIATE,
|
||||
Certs(_) => ChanCmd::CERTS,
|
||||
AuthChallenge(_) => ChanCmd::AUTH_CHALLENGE,
|
||||
Authenticate(_) => ChanCmd::AUTHENTICATE,
|
||||
Authorize(_) => ChanCmd::AUTHORIZE,
|
||||
Unrecognized(c) => c.cmd(),
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
|
||||
use ChanMsg::*;
|
||||
match self {
|
||||
Padding(b) => b.encode_onto(w),
|
||||
VPadding(b) => b.encode_onto(w),
|
||||
Create(b) => b.encode_onto(w),
|
||||
CreateFast(b) => b.encode_onto(w),
|
||||
Create2(b) => b.encode_onto(w),
|
||||
Created(b) => b.encode_onto(w),
|
||||
CreatedFast(b) => b.encode_onto(w),
|
||||
Created2(b) => b.encode_onto(w),
|
||||
Relay(b) => b.encode_onto(w),
|
||||
RelayEarly(b) => b.encode_onto(w),
|
||||
Destroy(b) => b.encode_onto(w),
|
||||
Netinfo(b) => b.encode_onto(w),
|
||||
Versions(b) => b.encode_onto(w),
|
||||
PaddingNegotiate(b) => b.encode_onto(w),
|
||||
Certs(b) => b.encode_onto(w),
|
||||
AuthChallenge(b) => b.encode_onto(w),
|
||||
Authenticate(b) => b.encode_onto(w),
|
||||
Authorize(b) => b.encode_onto(w),
|
||||
Unrecognized(b) => b.encode_onto(w),
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_from_reader(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Self> {
|
||||
use ChanMsg::*;
|
||||
Ok(match cmd {
|
||||
ChanCmd::PADDING => Padding(r.extract()?),
|
||||
ChanCmd::VPADDING => VPadding(r.extract()?),
|
||||
ChanCmd::CREATE => Create(r.extract()?),
|
||||
ChanCmd::CREATE_FAST => CreateFast(r.extract()?),
|
||||
ChanCmd::CREATE2 => Create2(r.extract()?),
|
||||
ChanCmd::CREATED => Created(r.extract()?),
|
||||
ChanCmd::CREATED_FAST => CreatedFast(r.extract()?),
|
||||
ChanCmd::CREATED2 => Created2(r.extract()?),
|
||||
ChanCmd::RELAY => Relay(r.extract()?),
|
||||
ChanCmd::RELAY_EARLY => RelayEarly(r.extract()?),
|
||||
ChanCmd::DESTROY => Destroy(r.extract()?),
|
||||
ChanCmd::NETINFO => Netinfo(r.extract()?),
|
||||
ChanCmd::VERSIONS => Versions(r.extract()?),
|
||||
ChanCmd::PADDING_NEGOTIATE => PaddingNegotiate(r.extract()?),
|
||||
ChanCmd::CERTS => Certs(r.extract()?),
|
||||
ChanCmd::AUTH_CHALLENGE => AuthChallenge(r.extract()?),
|
||||
ChanCmd::AUTHENTICATE => Authenticate(r.extract()?),
|
||||
ChanCmd::AUTHORIZE => Authorize(r.extract()?),
|
||||
_ => Unrecognized(crate::chancell::msg::Unrecognized::decode_with_cmd(cmd, r)?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ChanMsg {
|
||||
|
@ -206,31 +132,31 @@ impl Readable for Padding {
|
|||
///
|
||||
/// The correct response to a padding cell is to drop it and do nothing.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VPadding {
|
||||
pub struct Vpadding {
|
||||
/// How much padding to send in this cell's body.
|
||||
len: u16,
|
||||
}
|
||||
impl VPadding {
|
||||
impl Vpadding {
|
||||
/// Return a new vpadding cell with given length.
|
||||
pub fn new(len: u16) -> Self {
|
||||
VPadding { len }
|
||||
Vpadding { len }
|
||||
}
|
||||
}
|
||||
impl Body for VPadding {
|
||||
impl Body for Vpadding {
|
||||
fn into_message(self) -> ChanMsg {
|
||||
ChanMsg::VPadding(self)
|
||||
ChanMsg::Vpadding(self)
|
||||
}
|
||||
fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
|
||||
w.write_zeros(self.len as usize);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Readable for VPadding {
|
||||
impl Readable for Vpadding {
|
||||
fn take_from(r: &mut Reader<'_>) -> Result<Self> {
|
||||
if r.remaining() > std::u16::MAX as usize {
|
||||
return Err(Error::BadMessage("Too many bytes in VPADDING cell"));
|
||||
}
|
||||
Ok(VPadding {
|
||||
Ok(Vpadding {
|
||||
len: r.remaining() as u16,
|
||||
})
|
||||
}
|
||||
|
@ -520,6 +446,9 @@ impl Readable for Relay {
|
|||
}
|
||||
}
|
||||
|
||||
/// Alias for Relay: these two cell types have the same body.
|
||||
pub type RelayEarly = Relay;
|
||||
|
||||
/// The Destroy message tears down a circuit.
|
||||
///
|
||||
/// On receiving a Destroy message, a Tor implementation should
|
||||
|
@ -1279,7 +1208,7 @@ macro_rules! msg_into_cell {
|
|||
}
|
||||
|
||||
msg_into_cell!(Padding);
|
||||
msg_into_cell!(VPadding);
|
||||
msg_into_cell!(Vpadding);
|
||||
msg_into_cell!(Netinfo);
|
||||
msg_into_cell!(Versions);
|
||||
msg_into_cell!(PaddingNegotiate);
|
||||
|
|
|
@ -385,8 +385,8 @@ fn test_vpadding() {
|
|||
let cmd = ChanCmd::VPADDING;
|
||||
assert_eq!(Into::<u8>::into(cmd), 128_u8);
|
||||
|
||||
vbody(cmd, "", &msg::VPadding::new(0).into());
|
||||
vbody(cmd, "00000000000000000000", &msg::VPadding::new(10).into());
|
||||
vbody(cmd, "", &msg::Vpadding::new(0).into());
|
||||
vbody(cmd, "00000000000000000000", &msg::Vpadding::new(10).into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -245,7 +245,7 @@ impl Sink<ChanCell> for Channel {
|
|||
{
|
||||
use msg::ChanMsg::*;
|
||||
match cell.msg() {
|
||||
Relay(_) | Padding(_) | VPadding(_) => {} // too frequent to log.
|
||||
Relay(_) | Padding(_) | Vpadding(_) => {} // too frequent to log.
|
||||
_ => trace!(
|
||||
"{}: Sending {} for {}",
|
||||
this.details.unique_id,
|
||||
|
|
|
@ -226,7 +226,7 @@ impl<T: AsyncRead + AsyncWrite + Send + Unpin + 'static, S: SleepProvider>
|
|||
trace!("{}: received a {} cell.", self.unique_id, m.cmd());
|
||||
match m {
|
||||
// Are these technically allowed?
|
||||
Padding(_) | VPadding(_) => (),
|
||||
Padding(_) | Vpadding(_) => (),
|
||||
// Unrecognized cells get ignored.
|
||||
Unrecognized(_) => (),
|
||||
// Clients don't care about AuthChallenge
|
||||
|
|
|
@ -307,7 +307,7 @@ impl<S: SleepProvider> Reactor<S> {
|
|||
use ChanMsg::*;
|
||||
|
||||
match msg {
|
||||
Relay(_) | Padding(_) | VPadding(_) => {} // too frequent to log.
|
||||
Relay(_) | Padding(_) | Vpadding(_) => {} // too frequent to log.
|
||||
_ => trace!("{}: received {} for {}", &self, msg.cmd(), circid),
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ impl<S: SleepProvider> Reactor<S> {
|
|||
CreatedFast(_) | Created2(_) => self.deliver_created(circid, msg).await,
|
||||
|
||||
// These are always ignored.
|
||||
Padding(_) | VPadding(_) => Ok(()),
|
||||
Padding(_) | Vpadding(_) => Ok(()),
|
||||
|
||||
// Unrecognized cell types should be safe to allow _on channels_,
|
||||
// since they can't propagate.
|
||||
|
|
Loading…
Reference in New Issue