tor-proto: use caret_int!() for cell and relay commands.

This commit is contained in:
Nick Mathewson 2020-05-15 16:27:03 -04:00
parent 085a8250e7
commit 86894926aa
4 changed files with 155 additions and 173 deletions

View File

@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
publish = false
[dependencies]
caret = { path="../caret" }
tor-llcrypto = { path="../tor-llcrypto" }
tor-bytes = { path="../tor-bytes" }

View File

@ -10,6 +10,7 @@
#![allow(missing_docs)]
use caret::caret_int;
use tor_bytes::{Error, Reader, Result, Writer};
pub mod cellmsg;
@ -17,62 +18,60 @@ pub mod relaymsg;
pub const CELL_DATA_LEN: usize = 509;
type CellCmd = u8;
caret_int! {
pub struct ChanCmd(u8) {
PADDING = 0,
CREATE = 1,
CREATED = 2,
RELAY = 3,
DESTROY = 4,
CREATE_FAST = 5,
CREATED_FAST = 6,
// note gap.
NETINFO = 8,
RELAY_EARLY = 9,
CREATE2 = 10,
CREATED2 = 11,
PADDING_NEGOTIATE = 12,
// TODO: Instead of a module this should be an enum-like type (though not
// actually an enum).
pub mod cellcmd {
pub const PADDING: u8 = 0;
pub const CREATE: u8 = 1;
pub const CREATED: u8 = 2;
pub const RELAY: u8 = 3;
pub const DESTROY: u8 = 4;
pub const CREATE_FAST: u8 = 5;
pub const CREATED_FAST: u8 = 6;
// note gap.
pub const NETINFO: u8 = 8;
pub const RELAY_EARLY: u8 = 9;
pub const CREATE2: u8 = 10;
pub const CREATED2: u8 = 11;
pub const PADDING_NEGOTIATE: u8 = 12;
pub const VERSIONS: u8 = 7;
pub const VPADDING: u8 = 128;
pub const CERTS: u8 = 129;
pub const AUTH_CHALLENGE: u8 = 130;
pub const AUTHENTICATE: u8 = 131;
pub const AUTHORIZE: u8 = 132;
VERSIONS = 7,
VPADDING = 128,
CERTS = 129,
AUTH_CHALLENGE = 130,
AUTHENTICATE = 131,
AUTHORIZE = 132,
}
}
// TODO: Instead of a module this should be an enum-like type (though not
// actually an enum).
pub mod relaycmd {
pub const BEGIN: u8 = 1;
pub const DATA: u8 = 2;
pub const END: u8 = 3;
pub const CONNECTED: u8 = 4;
pub const SENDME: u8 = 5;
pub const EXTEND: u8 = 6;
pub const EXTENDED: u8 = 7;
pub const TRUNCATE: u8 = 8;
pub const TRUNCATED: u8 = 9;
pub const DROP: u8 = 10;
pub const RESOLVE: u8 = 11;
pub const RESOLVED: u8 = 12;
pub const BEGIN_DIR: u8 = 13;
pub const EXTEND2: u8 = 14;
pub const EXTENDED2: u8 = 15;
caret_int! {
pub struct StreamCmd(u8) {
BEGIN = 1,
DATA = 2,
END = 3,
CONNECTED = 4,
SENDME = 5,
EXTEND = 6,
EXTENDED = 7,
TRUNCATE = 8,
TRUNCATED = 9,
DROP = 10,
RESOLVE = 11,
RESOLVED = 12,
BEGIN_DIR = 13,
EXTEND2 = 14,
EXTENDED2 = 15,
// hs-related
pub const ESTABLISH_INTRO: u8 = 32;
pub const ESTABLISH_RENDEZVOUS: u8 = 33;
pub const INTRODUCE1: u8 = 34;
pub const INTRODUCE2: u8 = 35;
pub const RENDEZVOUS1: u8 = 36;
pub const RENDEZVOUS2: u8 = 37;
pub const INTRO_ESABLISHED: u8 = 38;
pub const RENDEZVOUS_ESABLISHED: u8 = 39;
pub const INTRODUCE_ACK: u8 = 40;
// hs-related
ESTABLISH_INTRO = 32,
ESTABLISH_RENDEZVOUS = 33,
INTRODUCE1 = 34,
INTRODUCE2 = 35,
RENDEZVOUS1 = 36,
RENDEZVOUS2 = 37,
INTRO_ESABLISHED = 38,
RENDEZVOUS_ESABLISHED = 39,
INTRODUCE_ACK = 40,
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@ -84,15 +83,6 @@ impl From<u32> for CircID {
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct ChanCmd(u8);
impl From<u8> for ChanCmd {
fn from(item: u8) -> Self {
Self(item)
}
}
#[derive(Clone)]
pub struct ChanCell {
circ: CircID,
@ -108,8 +98,6 @@ pub struct CellRef<'a> {
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct StreamID(u16);
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct StreamCmd(u8);
pub struct RelayCellRef<'a> {
pub stream: StreamID,
@ -124,7 +112,7 @@ pub struct ChannelProto {
impl ChanCmd {
pub fn is_var_cell(self) -> bool {
self.0 == cellcmd::VERSIONS as u8 || self.0 >= 128
self == ChanCmd::VERSIONS || self.0 >= 128u8
}
}

View File

@ -1,7 +1,7 @@
use crate::crypto::cell::{RawCellBody, CELL_BODY_LEN};
use tor_bytes::{Error, Reader, Result, Writer};
use super::{cellcmd, CellData, CellRef, ChanCell, CircID};
use super::{CellData, CellRef, ChanCell, ChanCmd, CircID};
use std::net::{IpAddr, Ipv4Addr};
@ -14,28 +14,24 @@ impl ChannelCell {
fn get_circid(&self) -> CircID {
self.circid
}
fn get_cmd(&self) -> u8 {
fn get_cmd(&self) -> ChanCmd {
self.body.get_cmd()
}
fn encode(self) -> ChanCell {
let cmd = self.get_cmd();
let circid = self.get_circid();
let circ = self.get_circid();
let body = self.body.encode();
ChanCell {
cmd: cmd.into(),
circ: circid,
body,
}
ChanCell { cmd, circ, body }
}
fn decode(c: ChanCell) -> Result<Self> {
let circid = c.get_circid();
let cmd = c.get_cmd().0;
let cmd = c.get_cmd();
let body = ChannelCellBody::decode(cmd, c.body)?;
Ok(ChannelCell { circid, body })
}
fn decode_ref(c: &CellRef<'_>) -> Result<Self> {
let circid = c.get_circid();
let cmd = c.get_cmd().0;
let cmd = c.get_cmd();
let mut r = Reader::from_slice(c.body);
let body = ChannelCellBody::decode_from_reader(cmd, &mut r)?;
Ok(ChannelCell { circid, body })
@ -62,32 +58,31 @@ pub enum ChannelCellBody {
AuthChallenge(AuthChallengeBody),
Authenticate(AuthenticateBody),
Authorize(AuthorizeBody),
Unrecognized(u8, UnrecognizedBody),
Unrecognized(ChanCmd, UnrecognizedBody),
}
impl ChannelCellBody {
pub fn get_cmd(&self) -> u8 {
use cellcmd::*;
pub fn get_cmd(&self) -> ChanCmd {
use ChannelCellBody::*;
match self {
Padding(_) => PADDING,
VPadding(_) => VPADDING,
Create(_) => CREATE,
CreateFast(_) => CREATE_FAST,
Create2(_) => CREATE2,
Created(_) => CREATED,
CreatedFast(_) => CREATED_FAST,
Created2(_) => CREATED2,
Relay(_) => RELAY,
RelayEarly(_) => RELAY_EARLY,
Destroy(_) => DESTROY,
Netinfo(_) => NETINFO,
Versions(_) => VERSIONS,
PaddingNegotiate(_) => PADDING_NEGOTIATE,
Certs(_) => CERTS,
AuthChallenge(_) => AUTH_CHALLENGE,
Authenticate(_) => AUTHENTICATE,
Authorize(_) => AUTHORIZE,
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,
}
}
@ -117,54 +112,54 @@ impl ChannelCellBody {
}
}
fn decode(cmd: u8, b: Vec<u8>) -> Result<Self> {
use cellcmd::*;
fn decode(cmd: ChanCmd, b: Vec<u8>) -> Result<Self> {
use ChannelCellBody::*;
Ok(match cmd {
PADDING => Padding(PaddingBody::decode(b)?),
VPADDING => VPadding(VPaddingBody::decode(b)?),
CREATE => Create(CreateBody::decode(b)?),
CREATE_FAST => CreateFast(CreateFastBody::decode(b)?),
CREATE2 => Create2(Create2Body::decode(b)?),
CREATED => Created(CreatedBody::decode(b)?),
CREATED_FAST => CreatedFast(CreatedFastBody::decode(b)?),
CREATED2 => Created2(Created2Body::decode(b)?),
RELAY => Relay(RelayBody::decode(b)?),
RELAY_EARLY => RelayEarly(RelayBody::decode(b)?),
DESTROY => Destroy(DestroyBody::decode(b)?),
NETINFO => Netinfo(NetinfoBody::decode(b)?),
VERSIONS => Versions(VersionsBody::decode(b)?),
PADDING_NEGOTIATE => PaddingNegotiate(PaddingNegotiateBody::decode(b)?),
CERTS => Certs(CertsBody::decode(b)?),
AUTH_CHALLENGE => AuthChallenge(AuthChallengeBody::decode(b)?),
AUTHENTICATE => Authenticate(AuthenticateBody::decode(b)?),
AUTHORIZE => Authorize(AuthorizeBody::decode(b)?),
ChanCmd::PADDING => Padding(PaddingBody::decode(b)?),
ChanCmd::VPADDING => VPadding(VPaddingBody::decode(b)?),
ChanCmd::CREATE => Create(CreateBody::decode(b)?),
ChanCmd::CREATE_FAST => CreateFast(CreateFastBody::decode(b)?),
ChanCmd::CREATE2 => Create2(Create2Body::decode(b)?),
ChanCmd::CREATED => Created(CreatedBody::decode(b)?),
ChanCmd::CREATED_FAST => CreatedFast(CreatedFastBody::decode(b)?),
ChanCmd::CREATED2 => Created2(Created2Body::decode(b)?),
ChanCmd::RELAY => Relay(RelayBody::decode(b)?),
ChanCmd::RELAY_EARLY => RelayEarly(RelayBody::decode(b)?),
ChanCmd::DESTROY => Destroy(DestroyBody::decode(b)?),
ChanCmd::NETINFO => Netinfo(NetinfoBody::decode(b)?),
ChanCmd::VERSIONS => Versions(VersionsBody::decode(b)?),
ChanCmd::PADDING_NEGOTIATE => PaddingNegotiate(PaddingNegotiateBody::decode(b)?),
ChanCmd::CERTS => Certs(CertsBody::decode(b)?),
ChanCmd::AUTH_CHALLENGE => AuthChallenge(AuthChallengeBody::decode(b)?),
ChanCmd::AUTHENTICATE => Authenticate(AuthenticateBody::decode(b)?),
ChanCmd::AUTHORIZE => Authorize(AuthorizeBody::decode(b)?),
_ => Unrecognized(cmd, UnrecognizedBody::decode(b)?),
})
}
fn decode_from_reader(cmd: u8, r: &mut Reader<'_>) -> Result<Self> {
use cellcmd::*;
fn decode_from_reader(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Self> {
use ChannelCellBody::*;
Ok(match cmd {
PADDING => Padding(PaddingBody::decode_from_reader(r)?),
VPADDING => VPadding(VPaddingBody::decode_from_reader(r)?),
CREATE => Create(CreateBody::decode_from_reader(r)?),
CREATE_FAST => CreateFast(CreateFastBody::decode_from_reader(r)?),
CREATE2 => Create2(Create2Body::decode_from_reader(r)?),
CREATED => Created(CreatedBody::decode_from_reader(r)?),
CREATED_FAST => CreatedFast(CreatedFastBody::decode_from_reader(r)?),
CREATED2 => Created2(Created2Body::decode_from_reader(r)?),
RELAY => Relay(RelayBody::decode_from_reader(r)?),
RELAY_EARLY => RelayEarly(RelayBody::decode_from_reader(r)?),
DESTROY => Destroy(DestroyBody::decode_from_reader(r)?),
NETINFO => Netinfo(NetinfoBody::decode_from_reader(r)?),
VERSIONS => Versions(VersionsBody::decode_from_reader(r)?),
PADDING_NEGOTIATE => PaddingNegotiate(PaddingNegotiateBody::decode_from_reader(r)?),
CERTS => Certs(CertsBody::decode_from_reader(r)?),
AUTH_CHALLENGE => AuthChallenge(AuthChallengeBody::decode_from_reader(r)?),
AUTHENTICATE => Authenticate(AuthenticateBody::decode_from_reader(r)?),
AUTHORIZE => Authorize(AuthorizeBody::decode_from_reader(r)?),
ChanCmd::PADDING => Padding(PaddingBody::decode_from_reader(r)?),
ChanCmd::VPADDING => VPadding(VPaddingBody::decode_from_reader(r)?),
ChanCmd::CREATE => Create(CreateBody::decode_from_reader(r)?),
ChanCmd::CREATE_FAST => CreateFast(CreateFastBody::decode_from_reader(r)?),
ChanCmd::CREATE2 => Create2(Create2Body::decode_from_reader(r)?),
ChanCmd::CREATED => Created(CreatedBody::decode_from_reader(r)?),
ChanCmd::CREATED_FAST => CreatedFast(CreatedFastBody::decode_from_reader(r)?),
ChanCmd::CREATED2 => Created2(Created2Body::decode_from_reader(r)?),
ChanCmd::RELAY => Relay(RelayBody::decode_from_reader(r)?),
ChanCmd::RELAY_EARLY => RelayEarly(RelayBody::decode_from_reader(r)?),
ChanCmd::DESTROY => Destroy(DestroyBody::decode_from_reader(r)?),
ChanCmd::NETINFO => Netinfo(NetinfoBody::decode_from_reader(r)?),
ChanCmd::VERSIONS => Versions(VersionsBody::decode_from_reader(r)?),
ChanCmd::PADDING_NEGOTIATE => {
PaddingNegotiate(PaddingNegotiateBody::decode_from_reader(r)?)
}
ChanCmd::CERTS => Certs(CertsBody::decode_from_reader(r)?),
ChanCmd::AUTH_CHALLENGE => AuthChallenge(AuthChallengeBody::decode_from_reader(r)?),
ChanCmd::AUTHENTICATE => Authenticate(AuthenticateBody::decode_from_reader(r)?),
ChanCmd::AUTHORIZE => Authorize(AuthorizeBody::decode_from_reader(r)?),
_ => Unrecognized(cmd, UnrecognizedBody::decode_from_reader(r)?),
})
}

View File

@ -1,5 +1,5 @@
use super::cellmsg::{TAP_C_HANDSHAKE_LEN, TAP_S_HANDSHAKE_LEN};
use super::relaycmd;
use super::StreamCmd;
use super::StreamID;
use std::net::{IpAddr, Ipv4Addr};
use tor_bytes::{Error, Result};
@ -17,7 +17,7 @@ pub struct RelayCell {
impl RelayCell {
fn encode(self) -> Vec<u8> {
let mut w = Vec::new();
w.write_u8(self.body.get_cmd());
w.write_u8(self.body.get_cmd().into());
w.write_u16(0); // "Recognized"
w.write_u16(self.streamid.0);
w.write_u32(0); // Digest
@ -32,7 +32,7 @@ impl RelayCell {
w
}
fn decode_from_reader(r: &mut Reader) -> Result<Self> {
let cmd = r.take_u8()?;
let cmd = r.take_u8()?.into();
r.advance(2)?; // "recognized"
let streamid = StreamID(r.take_u16()?);
r.advance(4)?; // digest
@ -63,7 +63,7 @@ pub enum RelayCellBody {
Resolved(ResolvedCellBody),
BeginDir,
Unrecognized(u8, UnrecognizedCellBody),
Unrecognized(StreamCmd, UnrecognizedCellBody),
// No hs for now.
}
@ -77,47 +77,45 @@ trait Body: Sized {
}
impl RelayCellBody {
pub fn get_cmd(&self) -> u8 {
use relaycmd::*;
pub fn get_cmd(&self) -> StreamCmd {
use RelayCellBody::*;
match self {
Begin(_) => BEGIN,
Data(_) => DATA,
End(_) => END,
Connected(_) => CONNECTED,
Sendme(_) => SENDME,
Extend(_) => EXTEND,
Extended(_) => EXTENDED,
Extend2(_) => EXTEND2,
Extended2(_) => EXTENDED2,
Truncate(_) => TRUNCATE,
Truncated(_) => TRUNCATED,
Drop => DROP,
Resolve(_) => RESOLVE,
Resolved(_) => RESOLVED,
BeginDir => BEGIN_DIR,
Begin(_) => StreamCmd::BEGIN,
Data(_) => StreamCmd::DATA,
End(_) => StreamCmd::END,
Connected(_) => StreamCmd::CONNECTED,
Sendme(_) => StreamCmd::SENDME,
Extend(_) => StreamCmd::EXTEND,
Extended(_) => StreamCmd::EXTENDED,
Extend2(_) => StreamCmd::EXTEND2,
Extended2(_) => StreamCmd::EXTENDED2,
Truncate(_) => StreamCmd::TRUNCATE,
Truncated(_) => StreamCmd::TRUNCATED,
Drop => StreamCmd::DROP,
Resolve(_) => StreamCmd::RESOLVE,
Resolved(_) => StreamCmd::RESOLVED,
BeginDir => StreamCmd::BEGIN_DIR,
Unrecognized(cmd, _) => *cmd,
}
}
pub fn decode_from_reader(c: u8, r: &mut Reader<'_>) -> Result<Self> {
use relaycmd::*;
pub fn decode_from_reader(c: StreamCmd, r: &mut Reader<'_>) -> Result<Self> {
use RelayCellBody::*;
Ok(match c {
BEGIN => Begin(BeginCellBody::decode_from_reader(r)?),
DATA => Data(DataCellBody::decode_from_reader(r)?),
END => End(EndCellBody::decode_from_reader(r)?),
CONNECTED => Connected(ConnectedCellBody::decode_from_reader(r)?),
SENDME => Sendme(SendmeCellBody::decode_from_reader(r)?),
EXTEND => Extend(ExtendCellBody::decode_from_reader(r)?),
EXTENDED => Extended(ExtendedCellBody::decode_from_reader(r)?),
EXTEND2 => Extend2(Extend2CellBody::decode_from_reader(r)?),
EXTENDED2 => Extended2(Extended2CellBody::decode_from_reader(r)?),
TRUNCATE => Truncate(TruncateCellBody::decode_from_reader(r)?),
TRUNCATED => Truncated(TruncatedCellBody::decode_from_reader(r)?),
DROP => Drop,
RESOLVE => Resolve(ResolveCellBody::decode_from_reader(r)?),
RESOLVED => Resolved(ResolvedCellBody::decode_from_reader(r)?),
BEGIN_DIR => BeginDir,
StreamCmd::BEGIN => Begin(BeginCellBody::decode_from_reader(r)?),
StreamCmd::DATA => Data(DataCellBody::decode_from_reader(r)?),
StreamCmd::END => End(EndCellBody::decode_from_reader(r)?),
StreamCmd::CONNECTED => Connected(ConnectedCellBody::decode_from_reader(r)?),
StreamCmd::SENDME => Sendme(SendmeCellBody::decode_from_reader(r)?),
StreamCmd::EXTEND => Extend(ExtendCellBody::decode_from_reader(r)?),
StreamCmd::EXTENDED => Extended(ExtendedCellBody::decode_from_reader(r)?),
StreamCmd::EXTEND2 => Extend2(Extend2CellBody::decode_from_reader(r)?),
StreamCmd::EXTENDED2 => Extended2(Extended2CellBody::decode_from_reader(r)?),
StreamCmd::TRUNCATE => Truncate(TruncateCellBody::decode_from_reader(r)?),
StreamCmd::TRUNCATED => Truncated(TruncatedCellBody::decode_from_reader(r)?),
StreamCmd::DROP => Drop,
StreamCmd::RESOLVE => Resolve(ResolveCellBody::decode_from_reader(r)?),
StreamCmd::RESOLVED => Resolved(ResolvedCellBody::decode_from_reader(r)?),
StreamCmd::BEGIN_DIR => BeginDir,
_ => Unrecognized(c, UnrecognizedCellBody::decode_from_reader(r)?),
})