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 publish = false
[dependencies] [dependencies]
caret = { path="../caret" }
tor-llcrypto = { path="../tor-llcrypto" } tor-llcrypto = { path="../tor-llcrypto" }
tor-bytes = { path="../tor-bytes" } tor-bytes = { path="../tor-bytes" }

View File

@ -10,6 +10,7 @@
#![allow(missing_docs)] #![allow(missing_docs)]
use caret::caret_int;
use tor_bytes::{Error, Reader, Result, Writer}; use tor_bytes::{Error, Reader, Result, Writer};
pub mod cellmsg; pub mod cellmsg;
@ -17,62 +18,60 @@ pub mod relaymsg;
pub const CELL_DATA_LEN: usize = 509; pub const CELL_DATA_LEN: usize = 509;
type CellCmd = u8; caret_int! {
pub struct ChanCmd(u8) {
// TODO: Instead of a module this should be an enum-like type (though not PADDING = 0,
// actually an enum). CREATE = 1,
pub mod cellcmd { CREATED = 2,
pub const PADDING: u8 = 0; RELAY = 3,
pub const CREATE: u8 = 1; DESTROY = 4,
pub const CREATED: u8 = 2; CREATE_FAST = 5,
pub const RELAY: u8 = 3; CREATED_FAST = 6,
pub const DESTROY: u8 = 4;
pub const CREATE_FAST: u8 = 5;
pub const CREATED_FAST: u8 = 6;
// note gap. // note gap.
pub const NETINFO: u8 = 8; NETINFO = 8,
pub const RELAY_EARLY: u8 = 9; RELAY_EARLY = 9,
pub const CREATE2: u8 = 10; CREATE2 = 10,
pub const CREATED2: u8 = 11; CREATED2 = 11,
pub const PADDING_NEGOTIATE: u8 = 12; PADDING_NEGOTIATE = 12,
pub const VERSIONS: u8 = 7; VERSIONS = 7,
pub const VPADDING: u8 = 128; VPADDING = 128,
pub const CERTS: u8 = 129; CERTS = 129,
pub const AUTH_CHALLENGE: u8 = 130; AUTH_CHALLENGE = 130,
pub const AUTHENTICATE: u8 = 131; AUTHENTICATE = 131,
pub const AUTHORIZE: u8 = 132; AUTHORIZE = 132,
}
} }
// TODO: Instead of a module this should be an enum-like type (though not caret_int! {
// actually an enum). pub struct StreamCmd(u8) {
pub mod relaycmd { BEGIN = 1,
pub const BEGIN: u8 = 1; DATA = 2,
pub const DATA: u8 = 2; END = 3,
pub const END: u8 = 3; CONNECTED = 4,
pub const CONNECTED: u8 = 4; SENDME = 5,
pub const SENDME: u8 = 5; EXTEND = 6,
pub const EXTEND: u8 = 6; EXTENDED = 7,
pub const EXTENDED: u8 = 7; TRUNCATE = 8,
pub const TRUNCATE: u8 = 8; TRUNCATED = 9,
pub const TRUNCATED: u8 = 9; DROP = 10,
pub const DROP: u8 = 10; RESOLVE = 11,
pub const RESOLVE: u8 = 11; RESOLVED = 12,
pub const RESOLVED: u8 = 12; BEGIN_DIR = 13,
pub const BEGIN_DIR: u8 = 13; EXTEND2 = 14,
pub const EXTEND2: u8 = 14; EXTENDED2 = 15,
pub const EXTENDED2: u8 = 15;
// hs-related // hs-related
pub const ESTABLISH_INTRO: u8 = 32; ESTABLISH_INTRO = 32,
pub const ESTABLISH_RENDEZVOUS: u8 = 33; ESTABLISH_RENDEZVOUS = 33,
pub const INTRODUCE1: u8 = 34; INTRODUCE1 = 34,
pub const INTRODUCE2: u8 = 35; INTRODUCE2 = 35,
pub const RENDEZVOUS1: u8 = 36; RENDEZVOUS1 = 36,
pub const RENDEZVOUS2: u8 = 37; RENDEZVOUS2 = 37,
pub const INTRO_ESABLISHED: u8 = 38; INTRO_ESABLISHED = 38,
pub const RENDEZVOUS_ESABLISHED: u8 = 39; RENDEZVOUS_ESABLISHED = 39,
pub const INTRODUCE_ACK: u8 = 40; INTRODUCE_ACK = 40,
}
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[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)] #[derive(Clone)]
pub struct ChanCell { pub struct ChanCell {
circ: CircID, circ: CircID,
@ -108,8 +98,6 @@ pub struct CellRef<'a> {
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct StreamID(u16); pub struct StreamID(u16);
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct StreamCmd(u8);
pub struct RelayCellRef<'a> { pub struct RelayCellRef<'a> {
pub stream: StreamID, pub stream: StreamID,
@ -124,7 +112,7 @@ pub struct ChannelProto {
impl ChanCmd { impl ChanCmd {
pub fn is_var_cell(self) -> bool { 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 crate::crypto::cell::{RawCellBody, CELL_BODY_LEN};
use tor_bytes::{Error, Reader, Result, Writer}; 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}; use std::net::{IpAddr, Ipv4Addr};
@ -14,28 +14,24 @@ impl ChannelCell {
fn get_circid(&self) -> CircID { fn get_circid(&self) -> CircID {
self.circid self.circid
} }
fn get_cmd(&self) -> u8 { fn get_cmd(&self) -> ChanCmd {
self.body.get_cmd() self.body.get_cmd()
} }
fn encode(self) -> ChanCell { fn encode(self) -> ChanCell {
let cmd = self.get_cmd(); let cmd = self.get_cmd();
let circid = self.get_circid(); let circ = self.get_circid();
let body = self.body.encode(); let body = self.body.encode();
ChanCell { ChanCell { cmd, circ, body }
cmd: cmd.into(),
circ: circid,
body,
}
} }
fn decode(c: ChanCell) -> Result<Self> { fn decode(c: ChanCell) -> Result<Self> {
let circid = c.get_circid(); let circid = c.get_circid();
let cmd = c.get_cmd().0; let cmd = c.get_cmd();
let body = ChannelCellBody::decode(cmd, c.body)?; let body = ChannelCellBody::decode(cmd, c.body)?;
Ok(ChannelCell { circid, body }) Ok(ChannelCell { circid, body })
} }
fn decode_ref(c: &CellRef<'_>) -> Result<Self> { fn decode_ref(c: &CellRef<'_>) -> Result<Self> {
let circid = c.get_circid(); 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 mut r = Reader::from_slice(c.body);
let body = ChannelCellBody::decode_from_reader(cmd, &mut r)?; let body = ChannelCellBody::decode_from_reader(cmd, &mut r)?;
Ok(ChannelCell { circid, body }) Ok(ChannelCell { circid, body })
@ -62,32 +58,31 @@ pub enum ChannelCellBody {
AuthChallenge(AuthChallengeBody), AuthChallenge(AuthChallengeBody),
Authenticate(AuthenticateBody), Authenticate(AuthenticateBody),
Authorize(AuthorizeBody), Authorize(AuthorizeBody),
Unrecognized(u8, UnrecognizedBody), Unrecognized(ChanCmd, UnrecognizedBody),
} }
impl ChannelCellBody { impl ChannelCellBody {
pub fn get_cmd(&self) -> u8 { pub fn get_cmd(&self) -> ChanCmd {
use cellcmd::*;
use ChannelCellBody::*; use ChannelCellBody::*;
match self { match self {
Padding(_) => PADDING, Padding(_) => ChanCmd::PADDING,
VPadding(_) => VPADDING, VPadding(_) => ChanCmd::VPADDING,
Create(_) => CREATE, Create(_) => ChanCmd::CREATE,
CreateFast(_) => CREATE_FAST, CreateFast(_) => ChanCmd::CREATE_FAST,
Create2(_) => CREATE2, Create2(_) => ChanCmd::CREATE2,
Created(_) => CREATED, Created(_) => ChanCmd::CREATED,
CreatedFast(_) => CREATED_FAST, CreatedFast(_) => ChanCmd::CREATED_FAST,
Created2(_) => CREATED2, Created2(_) => ChanCmd::CREATED2,
Relay(_) => RELAY, Relay(_) => ChanCmd::RELAY,
RelayEarly(_) => RELAY_EARLY, RelayEarly(_) => ChanCmd::RELAY_EARLY,
Destroy(_) => DESTROY, Destroy(_) => ChanCmd::DESTROY,
Netinfo(_) => NETINFO, Netinfo(_) => ChanCmd::NETINFO,
Versions(_) => VERSIONS, Versions(_) => ChanCmd::VERSIONS,
PaddingNegotiate(_) => PADDING_NEGOTIATE, PaddingNegotiate(_) => ChanCmd::PADDING_NEGOTIATE,
Certs(_) => CERTS, Certs(_) => ChanCmd::CERTS,
AuthChallenge(_) => AUTH_CHALLENGE, AuthChallenge(_) => ChanCmd::AUTH_CHALLENGE,
Authenticate(_) => AUTHENTICATE, Authenticate(_) => ChanCmd::AUTHENTICATE,
Authorize(_) => AUTHORIZE, Authorize(_) => ChanCmd::AUTHORIZE,
Unrecognized(c, _) => *c, Unrecognized(c, _) => *c,
} }
} }
@ -117,54 +112,54 @@ impl ChannelCellBody {
} }
} }
fn decode(cmd: u8, b: Vec<u8>) -> Result<Self> { fn decode(cmd: ChanCmd, b: Vec<u8>) -> Result<Self> {
use cellcmd::*;
use ChannelCellBody::*; use ChannelCellBody::*;
Ok(match cmd { Ok(match cmd {
PADDING => Padding(PaddingBody::decode(b)?), ChanCmd::PADDING => Padding(PaddingBody::decode(b)?),
VPADDING => VPadding(VPaddingBody::decode(b)?), ChanCmd::VPADDING => VPadding(VPaddingBody::decode(b)?),
CREATE => Create(CreateBody::decode(b)?), ChanCmd::CREATE => Create(CreateBody::decode(b)?),
CREATE_FAST => CreateFast(CreateFastBody::decode(b)?), ChanCmd::CREATE_FAST => CreateFast(CreateFastBody::decode(b)?),
CREATE2 => Create2(Create2Body::decode(b)?), ChanCmd::CREATE2 => Create2(Create2Body::decode(b)?),
CREATED => Created(CreatedBody::decode(b)?), ChanCmd::CREATED => Created(CreatedBody::decode(b)?),
CREATED_FAST => CreatedFast(CreatedFastBody::decode(b)?), ChanCmd::CREATED_FAST => CreatedFast(CreatedFastBody::decode(b)?),
CREATED2 => Created2(Created2Body::decode(b)?), ChanCmd::CREATED2 => Created2(Created2Body::decode(b)?),
RELAY => Relay(RelayBody::decode(b)?), ChanCmd::RELAY => Relay(RelayBody::decode(b)?),
RELAY_EARLY => RelayEarly(RelayBody::decode(b)?), ChanCmd::RELAY_EARLY => RelayEarly(RelayBody::decode(b)?),
DESTROY => Destroy(DestroyBody::decode(b)?), ChanCmd::DESTROY => Destroy(DestroyBody::decode(b)?),
NETINFO => Netinfo(NetinfoBody::decode(b)?), ChanCmd::NETINFO => Netinfo(NetinfoBody::decode(b)?),
VERSIONS => Versions(VersionsBody::decode(b)?), ChanCmd::VERSIONS => Versions(VersionsBody::decode(b)?),
PADDING_NEGOTIATE => PaddingNegotiate(PaddingNegotiateBody::decode(b)?), ChanCmd::PADDING_NEGOTIATE => PaddingNegotiate(PaddingNegotiateBody::decode(b)?),
CERTS => Certs(CertsBody::decode(b)?), ChanCmd::CERTS => Certs(CertsBody::decode(b)?),
AUTH_CHALLENGE => AuthChallenge(AuthChallengeBody::decode(b)?), ChanCmd::AUTH_CHALLENGE => AuthChallenge(AuthChallengeBody::decode(b)?),
AUTHENTICATE => Authenticate(AuthenticateBody::decode(b)?), ChanCmd::AUTHENTICATE => Authenticate(AuthenticateBody::decode(b)?),
AUTHORIZE => Authorize(AuthorizeBody::decode(b)?), ChanCmd::AUTHORIZE => Authorize(AuthorizeBody::decode(b)?),
_ => Unrecognized(cmd, UnrecognizedBody::decode(b)?), _ => Unrecognized(cmd, UnrecognizedBody::decode(b)?),
}) })
} }
fn decode_from_reader(cmd: u8, r: &mut Reader<'_>) -> Result<Self> { fn decode_from_reader(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Self> {
use cellcmd::*;
use ChannelCellBody::*; use ChannelCellBody::*;
Ok(match cmd { Ok(match cmd {
PADDING => Padding(PaddingBody::decode_from_reader(r)?), ChanCmd::PADDING => Padding(PaddingBody::decode_from_reader(r)?),
VPADDING => VPadding(VPaddingBody::decode_from_reader(r)?), ChanCmd::VPADDING => VPadding(VPaddingBody::decode_from_reader(r)?),
CREATE => Create(CreateBody::decode_from_reader(r)?), ChanCmd::CREATE => Create(CreateBody::decode_from_reader(r)?),
CREATE_FAST => CreateFast(CreateFastBody::decode_from_reader(r)?), ChanCmd::CREATE_FAST => CreateFast(CreateFastBody::decode_from_reader(r)?),
CREATE2 => Create2(Create2Body::decode_from_reader(r)?), ChanCmd::CREATE2 => Create2(Create2Body::decode_from_reader(r)?),
CREATED => Created(CreatedBody::decode_from_reader(r)?), ChanCmd::CREATED => Created(CreatedBody::decode_from_reader(r)?),
CREATED_FAST => CreatedFast(CreatedFastBody::decode_from_reader(r)?), ChanCmd::CREATED_FAST => CreatedFast(CreatedFastBody::decode_from_reader(r)?),
CREATED2 => Created2(Created2Body::decode_from_reader(r)?), ChanCmd::CREATED2 => Created2(Created2Body::decode_from_reader(r)?),
RELAY => Relay(RelayBody::decode_from_reader(r)?), ChanCmd::RELAY => Relay(RelayBody::decode_from_reader(r)?),
RELAY_EARLY => RelayEarly(RelayBody::decode_from_reader(r)?), ChanCmd::RELAY_EARLY => RelayEarly(RelayBody::decode_from_reader(r)?),
DESTROY => Destroy(DestroyBody::decode_from_reader(r)?), ChanCmd::DESTROY => Destroy(DestroyBody::decode_from_reader(r)?),
NETINFO => Netinfo(NetinfoBody::decode_from_reader(r)?), ChanCmd::NETINFO => Netinfo(NetinfoBody::decode_from_reader(r)?),
VERSIONS => Versions(VersionsBody::decode_from_reader(r)?), ChanCmd::VERSIONS => Versions(VersionsBody::decode_from_reader(r)?),
PADDING_NEGOTIATE => PaddingNegotiate(PaddingNegotiateBody::decode_from_reader(r)?), ChanCmd::PADDING_NEGOTIATE => {
CERTS => Certs(CertsBody::decode_from_reader(r)?), PaddingNegotiate(PaddingNegotiateBody::decode_from_reader(r)?)
AUTH_CHALLENGE => AuthChallenge(AuthChallengeBody::decode_from_reader(r)?), }
AUTHENTICATE => Authenticate(AuthenticateBody::decode_from_reader(r)?), ChanCmd::CERTS => Certs(CertsBody::decode_from_reader(r)?),
AUTHORIZE => Authorize(AuthorizeBody::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)?), _ => 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::cellmsg::{TAP_C_HANDSHAKE_LEN, TAP_S_HANDSHAKE_LEN};
use super::relaycmd; use super::StreamCmd;
use super::StreamID; use super::StreamID;
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
use tor_bytes::{Error, Result}; use tor_bytes::{Error, Result};
@ -17,7 +17,7 @@ pub struct RelayCell {
impl RelayCell { impl RelayCell {
fn encode(self) -> Vec<u8> { fn encode(self) -> Vec<u8> {
let mut w = Vec::new(); 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(0); // "Recognized"
w.write_u16(self.streamid.0); w.write_u16(self.streamid.0);
w.write_u32(0); // Digest w.write_u32(0); // Digest
@ -32,7 +32,7 @@ impl RelayCell {
w w
} }
fn decode_from_reader(r: &mut Reader) -> Result<Self> { fn decode_from_reader(r: &mut Reader) -> Result<Self> {
let cmd = r.take_u8()?; let cmd = r.take_u8()?.into();
r.advance(2)?; // "recognized" r.advance(2)?; // "recognized"
let streamid = StreamID(r.take_u16()?); let streamid = StreamID(r.take_u16()?);
r.advance(4)?; // digest r.advance(4)?; // digest
@ -63,7 +63,7 @@ pub enum RelayCellBody {
Resolved(ResolvedCellBody), Resolved(ResolvedCellBody),
BeginDir, BeginDir,
Unrecognized(u8, UnrecognizedCellBody), Unrecognized(StreamCmd, UnrecognizedCellBody),
// No hs for now. // No hs for now.
} }
@ -77,47 +77,45 @@ trait Body: Sized {
} }
impl RelayCellBody { impl RelayCellBody {
pub fn get_cmd(&self) -> u8 { pub fn get_cmd(&self) -> StreamCmd {
use relaycmd::*;
use RelayCellBody::*; use RelayCellBody::*;
match self { match self {
Begin(_) => BEGIN, Begin(_) => StreamCmd::BEGIN,
Data(_) => DATA, Data(_) => StreamCmd::DATA,
End(_) => END, End(_) => StreamCmd::END,
Connected(_) => CONNECTED, Connected(_) => StreamCmd::CONNECTED,
Sendme(_) => SENDME, Sendme(_) => StreamCmd::SENDME,
Extend(_) => EXTEND, Extend(_) => StreamCmd::EXTEND,
Extended(_) => EXTENDED, Extended(_) => StreamCmd::EXTENDED,
Extend2(_) => EXTEND2, Extend2(_) => StreamCmd::EXTEND2,
Extended2(_) => EXTENDED2, Extended2(_) => StreamCmd::EXTENDED2,
Truncate(_) => TRUNCATE, Truncate(_) => StreamCmd::TRUNCATE,
Truncated(_) => TRUNCATED, Truncated(_) => StreamCmd::TRUNCATED,
Drop => DROP, Drop => StreamCmd::DROP,
Resolve(_) => RESOLVE, Resolve(_) => StreamCmd::RESOLVE,
Resolved(_) => RESOLVED, Resolved(_) => StreamCmd::RESOLVED,
BeginDir => BEGIN_DIR, BeginDir => StreamCmd::BEGIN_DIR,
Unrecognized(cmd, _) => *cmd, Unrecognized(cmd, _) => *cmd,
} }
} }
pub fn decode_from_reader(c: u8, r: &mut Reader<'_>) -> Result<Self> { pub fn decode_from_reader(c: StreamCmd, r: &mut Reader<'_>) -> Result<Self> {
use relaycmd::*;
use RelayCellBody::*; use RelayCellBody::*;
Ok(match c { Ok(match c {
BEGIN => Begin(BeginCellBody::decode_from_reader(r)?), StreamCmd::BEGIN => Begin(BeginCellBody::decode_from_reader(r)?),
DATA => Data(DataCellBody::decode_from_reader(r)?), StreamCmd::DATA => Data(DataCellBody::decode_from_reader(r)?),
END => End(EndCellBody::decode_from_reader(r)?), StreamCmd::END => End(EndCellBody::decode_from_reader(r)?),
CONNECTED => Connected(ConnectedCellBody::decode_from_reader(r)?), StreamCmd::CONNECTED => Connected(ConnectedCellBody::decode_from_reader(r)?),
SENDME => Sendme(SendmeCellBody::decode_from_reader(r)?), StreamCmd::SENDME => Sendme(SendmeCellBody::decode_from_reader(r)?),
EXTEND => Extend(ExtendCellBody::decode_from_reader(r)?), StreamCmd::EXTEND => Extend(ExtendCellBody::decode_from_reader(r)?),
EXTENDED => Extended(ExtendedCellBody::decode_from_reader(r)?), StreamCmd::EXTENDED => Extended(ExtendedCellBody::decode_from_reader(r)?),
EXTEND2 => Extend2(Extend2CellBody::decode_from_reader(r)?), StreamCmd::EXTEND2 => Extend2(Extend2CellBody::decode_from_reader(r)?),
EXTENDED2 => Extended2(Extended2CellBody::decode_from_reader(r)?), StreamCmd::EXTENDED2 => Extended2(Extended2CellBody::decode_from_reader(r)?),
TRUNCATE => Truncate(TruncateCellBody::decode_from_reader(r)?), StreamCmd::TRUNCATE => Truncate(TruncateCellBody::decode_from_reader(r)?),
TRUNCATED => Truncated(TruncatedCellBody::decode_from_reader(r)?), StreamCmd::TRUNCATED => Truncated(TruncatedCellBody::decode_from_reader(r)?),
DROP => Drop, StreamCmd::DROP => Drop,
RESOLVE => Resolve(ResolveCellBody::decode_from_reader(r)?), StreamCmd::RESOLVE => Resolve(ResolveCellBody::decode_from_reader(r)?),
RESOLVED => Resolved(ResolvedCellBody::decode_from_reader(r)?), StreamCmd::RESOLVED => Resolved(ResolvedCellBody::decode_from_reader(r)?),
BEGIN_DIR => BeginDir, StreamCmd::BEGIN_DIR => BeginDir,
_ => Unrecognized(c, UnrecognizedCellBody::decode_from_reader(r)?), _ => Unrecognized(c, UnrecognizedCellBody::decode_from_reader(r)?),
}) })