1use super::{BoxedCellBody, CELL_DATA_LEN, ChanCmd, RawCellBody};
4use std::net::{IpAddr, Ipv4Addr};
5use tor_basic_utils::skip_fmt;
6use tor_bytes::{self, EncodeError, EncodeResult, Error, Readable, Reader, Result, Writer};
7use tor_memquota::derive_deftly_template_HasMemoryCost;
8use tor_units::IntegerMilliseconds;
9
10use caret::caret_int;
11use derive_deftly::Deftly;
12use educe::Educe;
13
14pub trait Body: Readable {
16    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
18        r.extract()
19    }
20    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()>;
25}
26
27crate::restrict::restricted_msg! {
28#[derive(Clone, Debug, Deftly)]
34#[derive_deftly(HasMemoryCost)]
35#[non_exhaustive]
36@omit_from "avoid_conflict_with_a_blanket_implementation"
37pub enum AnyChanMsg : ChanMsg {
38    Padding,
40    Vpadding,
42    Create,
44    CreateFast,
46    Create2,
48    Created,
50    CreatedFast,
52    Created2,
54    Relay,
56    RelayEarly,
58    Destroy,
60    Netinfo,
62    Versions,
65    PaddingNegotiate,
67    Certs,
70    AuthChallenge,
73    Authenticate,
76    _ =>
77    Unrecognized,
79}
80}
81
82#[derive(Clone, Debug, Default, Deftly)]
90#[derive_deftly(HasMemoryCost)]
91#[non_exhaustive]
92pub struct Padding {}
93impl Padding {
94    pub fn new() -> Self {
96        Padding {}
97    }
98}
99impl Body for Padding {
100    fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
101        Ok(())
102    }
103}
104impl Readable for Padding {
105    fn take_from(_b: &mut Reader<'_>) -> Result<Self> {
106        Ok(Padding {})
107    }
108}
109
110#[derive(Clone, Debug, Deftly)]
114#[derive_deftly(HasMemoryCost)]
115pub struct Vpadding {
116    len: u16,
118}
119impl Vpadding {
120    pub fn new(len: u16) -> Self {
122        Vpadding { len }
123    }
124}
125impl Body for Vpadding {
126    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
127        w.write_zeros(self.len as usize);
128        Ok(())
129    }
130}
131impl Readable for Vpadding {
132    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
133        if b.remaining() > u16::MAX as usize {
134            return Err(Error::InvalidMessage(
135                "Too many bytes in VPADDING cell".into(),
136            ));
137        }
138        Ok(Vpadding {
139            len: b.remaining() as u16,
140        })
141    }
142}
143
144macro_rules! fixed_len_handshake {
147    {
148        $(#[$meta:meta])*
149        $name:ident , $cmd:ident, $len:ident
150    } => {
151        $(#[$meta])*
152        #[derive(Clone,Debug,Deftly)]
153        #[derive_deftly(HasMemoryCost)]
154        pub struct $name {
155            handshake: Vec<u8>
156        }
157        impl $name {
158            pub fn new<B>(handshake: B) -> Self
160                where B: Into<Vec<u8>>
161            {
162                let handshake = handshake.into();
163                $name { handshake }
164            }
165        }
166        impl Body for $name {
167            fn encode_onto<W: Writer + ?Sized>(self, w: &mut W)  -> EncodeResult<()> {
168                w.write_all(&self.handshake[..]);
169                Ok(())
170            }
171        }
172        impl Readable for $name {
173            fn take_from(b: &mut Reader<'_>) -> Result<Self> {
174                Ok($name {
175                    handshake: b.take($len)?.into(),
176                })
177            }
178        }
179    }
180}
181
182pub(crate) const TAP_C_HANDSHAKE_LEN: usize = 128 + 16 + 42;
184pub(crate) const TAP_S_HANDSHAKE_LEN: usize = 128 + 20;
186
187const FAST_C_HANDSHAKE_LEN: usize = 20;
189const FAST_S_HANDSHAKE_LEN: usize = 20 + 20;
191
192fixed_len_handshake! {
193    Create, CREATE, TAP_C_HANDSHAKE_LEN
202}
203fixed_len_handshake! {
204    Created, CREATED, TAP_S_HANDSHAKE_LEN
209}
210fixed_len_handshake! {
211    CreateFast, CREATE_FAST, FAST_C_HANDSHAKE_LEN
223}
224impl CreateFast {
225    pub fn handshake(&self) -> &[u8] {
227        &self.handshake
228    }
229}
230fixed_len_handshake! {
231    CreatedFast, CREATED_FAST, FAST_S_HANDSHAKE_LEN
236}
237impl CreatedFast {
238    pub fn into_handshake(self) -> Vec<u8> {
240        self.handshake
241    }
242}
243
244caret_int! {
245    #[derive(Deftly)]
248    #[derive_deftly(HasMemoryCost)]
249    pub struct HandshakeType(u16) {
250        TAP = 0,
252
253        NTOR = 2,
257        NTOR_V3 = 3,
259    }
260}
261
262#[derive(Clone, Debug, Deftly)]
271#[derive_deftly(HasMemoryCost)]
272pub struct Create2 {
273    handshake_type: HandshakeType,
275    handshake: Vec<u8>,
277}
278impl Body for Create2 {
279    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
280        w.write_u16(self.handshake_type.into());
281        let handshake_len = self
282            .handshake
283            .len()
284            .try_into()
285            .map_err(|_| EncodeError::BadLengthValue)?;
286        w.write_u16(handshake_len);
287        w.write_all(&self.handshake[..]);
288        Ok(())
289    }
290}
291impl Readable for Create2 {
292    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
293        let handshake_type = HandshakeType::from(b.take_u16()?);
294        let hlen = b.take_u16()?;
295        let handshake = b.take(hlen as usize)?.into();
296        Ok(Create2 {
297            handshake_type,
298            handshake,
299        })
300    }
301}
302impl Create2 {
303    pub fn new<B>(handshake_type: HandshakeType, handshake: B) -> Self
305    where
306        B: Into<Vec<u8>>,
307    {
308        let handshake = handshake.into();
309        Create2 {
310            handshake_type,
311            handshake,
312        }
313    }
314
315    pub fn handshake_type(&self) -> HandshakeType {
317        self.handshake_type
318    }
319
320    pub fn body(&self) -> &[u8] {
322        &self.handshake[..]
323    }
324}
325
326#[derive(Clone, Debug, Deftly)]
331#[derive_deftly(HasMemoryCost)]
332pub struct Created2 {
333    handshake: Vec<u8>,
335}
336impl Created2 {
337    pub fn new<B>(handshake: B) -> Self
339    where
340        B: Into<Vec<u8>>,
341    {
342        let handshake = handshake.into();
343        Created2 { handshake }
344    }
345    pub fn into_body(self) -> Vec<u8> {
347        self.handshake
348    }
349}
350impl Body for Created2 {
351    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
352        let handshake_len = self
353            .handshake
354            .len()
355            .try_into()
356            .map_err(|_| EncodeError::BadLengthValue)?;
357        w.write_u16(handshake_len);
358        w.write_all(&self.handshake[..]);
359        Ok(())
360    }
361}
362impl Readable for Created2 {
363    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
364        let hlen = b.take_u16()?;
365        let handshake = b.take(hlen as usize)?.into();
366        Ok(Created2 { handshake })
367    }
368}
369
370#[derive(Clone, Educe, derive_more::From, Deftly)]
381#[derive_deftly(HasMemoryCost)]
382#[educe(Debug)]
383pub struct Relay {
384    #[educe(Debug(method = "skip_fmt"))]
392    body: BoxedCellBody,
393}
394impl Relay {
395    pub fn new<P>(body: P) -> Self
397    where
398        P: AsRef<[u8]>,
399    {
400        let body = body.as_ref();
401        let mut r = [0_u8; CELL_DATA_LEN];
402        r[..body.len()].copy_from_slice(body);
405        Relay { body: Box::new(r) }
406    }
407    pub fn from_raw(body: RawCellBody) -> Self {
409        Relay {
410            body: Box::new(body),
411        }
412    }
413    pub fn into_relay_body(self) -> BoxedCellBody {
416        self.body
417    }
418    pub fn into_early(self) -> AnyChanMsg {
420        AnyChanMsg::RelayEarly(RelayEarly(self))
421    }
422}
423impl Body for Relay {
424    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
425        w.write_all(&self.body[..]);
426        Ok(())
427    }
428}
429impl Readable for Relay {
430    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
431        let mut body = Box::new([0_u8; CELL_DATA_LEN]);
432        body.copy_from_slice(b.take(CELL_DATA_LEN)?);
433        Ok(Relay { body })
434    }
435}
436
437#[derive(Clone, Debug, derive_more::Deref, derive_more::From, derive_more::Into, Deftly)]
441#[derive_deftly(HasMemoryCost)]
442pub struct RelayEarly(Relay);
443impl Readable for RelayEarly {
444    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
445        Ok(RelayEarly(Relay::take_from(r)?))
446    }
447}
448impl Body for RelayEarly {
449    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
450        self.0.encode_onto(w)
451    }
452}
453impl RelayEarly {
454    pub fn into_relay_body(self) -> BoxedCellBody {
460        self.0.body
461    }
462}
463
464#[derive(Clone, Debug, Deftly)]
470#[derive_deftly(HasMemoryCost)]
471pub struct Destroy {
472    reason: DestroyReason,
474}
475impl Destroy {
476    pub fn new(reason: DestroyReason) -> Self {
478        Destroy { reason }
479    }
480    pub fn reason(&self) -> DestroyReason {
482        self.reason
483    }
484}
485impl Body for Destroy {
486    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
487        w.write_u8(self.reason.into());
488        Ok(())
489    }
490}
491impl Readable for Destroy {
492    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
493        let reason = r.take_u8()?.into();
494        Ok(Destroy { reason })
495    }
496}
497
498caret_int! {
499    #[derive(Deftly)]
501    #[derive_deftly(HasMemoryCost)]
502    pub struct DestroyReason(u8) {
503        NONE = 0,
507        PROTOCOL = 1,
509        INTERNAL = 2,
511        REQUESTED = 3,
513        HIBERNATING = 4,
515        RESOURCELIMIT = 5,
517        CONNECTFAILED = 6,
519        OR_IDENTITY = 7,
521        CHANNEL_CLOSED = 8,
523        FINISHED = 9,
525        TIMEOUT = 10,
527        DESTROYED = 11,
529        NOSUCHSERVICE = 12
531    }
532}
533
534impl DestroyReason {
535    pub fn human_str(&self) -> &'static str {
537        match *self {
538            DestroyReason::NONE => "No reason",
539            DestroyReason::PROTOCOL => "Protocol violation",
540            DestroyReason::INTERNAL => "Internal error",
541            DestroyReason::REQUESTED => "Client sent a TRUNCATE command",
542            DestroyReason::HIBERNATING => "Relay is hibernating and not accepting requests",
543            DestroyReason::RESOURCELIMIT => "Relay ran out of resources",
544            DestroyReason::CONNECTFAILED => "Couldn't connect to relay",
545            DestroyReason::OR_IDENTITY => "Connected to relay with different OR identity",
546            DestroyReason::CHANNEL_CLOSED => "The OR channels carrying this circuit died",
547            DestroyReason::FINISHED => "Circuit expired for being too dirty or old",
548            DestroyReason::TIMEOUT => "Circuit construction took too long",
549            DestroyReason::DESTROYED => "Circuit was destroyed without client truncate",
550            DestroyReason::NOSUCHSERVICE => "No such onion service",
551            _ => "Unrecognized reason",
552        }
553    }
554}
555
556#[derive(Clone, Debug, Deftly)]
564#[derive_deftly(HasMemoryCost)]
565pub struct Netinfo {
566    timestamp: u32,
572    their_addr: Option<IpAddr>,
574    my_addr: Vec<IpAddr>,
576}
577fn enc_one_netinfo_addr<W: Writer + ?Sized>(w: &mut W, addr: &IpAddr) {
579    match addr {
580        IpAddr::V4(ipv4) => {
581            w.write_u8(0x04); w.write_u8(4); w.write_all(&ipv4.octets()[..]);
584        }
585        IpAddr::V6(ipv6) => {
586            w.write_u8(0x06); w.write_u8(16); w.write_all(&ipv6.octets()[..]);
589        }
590    }
591}
592fn take_one_netinfo_addr(r: &mut Reader<'_>) -> Result<Option<IpAddr>> {
594    let atype = r.take_u8()?;
595    let alen = r.take_u8()?;
596    let abody = r.take(alen as usize)?;
597    match (atype, alen) {
598        (0x04, 4) => {
599            let bytes = [abody[0], abody[1], abody[2], abody[3]];
600            Ok(Some(IpAddr::V4(bytes.into())))
601        }
602        (0x06, 16) => {
603            let mut bytes = [0_u8; 16];
605            bytes.copy_from_slice(abody);
606            Ok(Some(IpAddr::V6(bytes.into())))
607        }
608        (_, _) => Ok(None),
609    }
610}
611impl Netinfo {
612    pub fn from_client(their_addr: Option<IpAddr>) -> Self {
614        Netinfo {
615            timestamp: 0, their_addr,
617            my_addr: Vec::new(), }
619    }
620    pub fn from_relay<V>(timestamp: u32, their_addr: Option<IpAddr>, my_addrs: V) -> Self
622    where
623        V: Into<Vec<IpAddr>>,
624    {
625        let my_addr = my_addrs.into();
626        Netinfo {
627            timestamp,
628            their_addr,
629            my_addr,
630        }
631    }
632    pub fn timestamp(&self) -> Option<std::time::SystemTime> {
634        use std::time::{Duration, SystemTime};
635        if self.timestamp == 0 {
636            None
637        } else {
638            Some(SystemTime::UNIX_EPOCH + Duration::from_secs(self.timestamp.into()))
639        }
640    }
641}
642impl Body for Netinfo {
643    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
644        w.write_u32(self.timestamp);
645        let their_addr = self
646            .their_addr
647            .unwrap_or_else(|| Ipv4Addr::UNSPECIFIED.into());
648        enc_one_netinfo_addr(w, &their_addr);
649        let n_addrs: u8 = self
650            .my_addr
651            .len()
652            .try_into()
653            .map_err(|_| EncodeError::BadLengthValue)?;
654        w.write_u8(n_addrs);
655        for addr in &self.my_addr {
656            enc_one_netinfo_addr(w, addr);
657        }
658        Ok(())
659    }
660}
661impl Readable for Netinfo {
662    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
663        let timestamp = r.take_u32()?;
664        let their_addr = take_one_netinfo_addr(r)?.filter(|a| !a.is_unspecified());
665        let my_n_addrs = r.take_u8()?;
666        let mut my_addr = Vec::with_capacity(my_n_addrs as usize);
667        for _ in 0..my_n_addrs {
668            if let Some(a) = take_one_netinfo_addr(r)? {
669                my_addr.push(a);
670            }
671        }
672        Ok(Netinfo {
673            timestamp,
674            their_addr,
675            my_addr,
676        })
677    }
678}
679
680#[derive(Clone, Debug, Deftly)]
690#[derive_deftly(HasMemoryCost)]
691pub struct Versions {
692    versions: Vec<u16>,
694}
695impl Versions {
696    pub fn new<B>(vs: B) -> crate::Result<Self>
701    where
702        B: Into<Vec<u16>>,
703    {
704        let versions = vs.into();
705        if versions.len() < (u16::MAX / 2) as usize {
706            Ok(Self { versions })
707        } else {
708            Err(crate::Error::CantEncode("Too many versions"))
709        }
710    }
711    pub fn encode_for_handshake(self) -> EncodeResult<Vec<u8>> {
717        let mut v = Vec::new();
718        v.write_u16(0); v.write_u8(ChanCmd::VERSIONS.into());
720        v.write_u16((self.versions.len() * 2) as u16); self.encode_onto(&mut v)?;
722        Ok(v)
723    }
724    pub fn best_shared_link_protocol(&self, my_protos: &[u16]) -> Option<u16> {
727        let p = my_protos
730            .iter()
731            .filter(|p| self.versions.contains(p))
732            .fold(0_u16, |a, b| u16::max(a, *b));
733        if p == 0 { None } else { Some(p) }
734    }
735}
736impl Body for Versions {
737    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
738        for v in &self.versions {
739            w.write_u16(*v);
740        }
741        Ok(())
742    }
743}
744impl Readable for Versions {
745    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
746        let mut versions = Vec::new();
747        while r.remaining() > 0 {
748            versions.push(r.take_u16()?);
749        }
750        Ok(Versions { versions })
751    }
752}
753
754caret_int! {
755    #[derive(Deftly)]
758    #[derive_deftly(HasMemoryCost)]
759    pub struct PaddingNegotiateCmd(u8) {
760        START = 2,
762
763        STOP = 1,
765    }
766}
767
768#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
780#[derive_deftly(HasMemoryCost)]
781pub struct PaddingNegotiate {
782    command: PaddingNegotiateCmd,
784    ito_low_ms: u16,
787    ito_high_ms: u16,
790}
791impl PaddingNegotiate {
792    pub fn start_default() -> Self {
796        Self {
798            command: PaddingNegotiateCmd::START,
799            ito_low_ms: 0,
800            ito_high_ms: 0,
801        }
802    }
803
804    pub fn start(ito_low: IntegerMilliseconds<u16>, ito_high: IntegerMilliseconds<u16>) -> Self {
806        Self {
808            command: PaddingNegotiateCmd::START,
809            ito_low_ms: ito_low.as_millis(),
810            ito_high_ms: ito_high.as_millis(),
811        }
812    }
813
814    pub fn stop() -> Self {
816        Self {
818            command: PaddingNegotiateCmd::STOP,
819            ito_low_ms: 0,
820            ito_high_ms: 0,
821        }
822    }
823
824    #[cfg(feature = "testing")]
828    pub fn from_raw(command: PaddingNegotiateCmd, ito_low_ms: u16, ito_high_ms: u16) -> Self {
829        PaddingNegotiate {
830            command,
831            ito_low_ms,
832            ito_high_ms,
833        }
834    }
835}
836impl Default for PaddingNegotiate {
837    fn default() -> Self {
838        Self::start_default()
839    }
840}
841
842impl Body for PaddingNegotiate {
843    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
844        w.write_u8(0); w.write_u8(self.command.get());
846        w.write_u16(self.ito_low_ms);
847        w.write_u16(self.ito_high_ms);
848        Ok(())
849    }
850}
851impl Readable for PaddingNegotiate {
852    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
853        let v = r.take_u8()?;
854        if v != 0 {
855            return Err(Error::InvalidMessage(
856                "Unrecognized padding negotiation version".into(),
857            ));
858        }
859        let command = r.take_u8()?.into();
860        let ito_low_ms = r.take_u16()?;
861        let ito_high_ms = r.take_u16()?;
862        Ok(PaddingNegotiate {
863            command,
864            ito_low_ms,
865            ito_high_ms,
866        })
867    }
868}
869
870#[derive(Clone, Debug, Deftly)]
875#[derive_deftly(HasMemoryCost)]
876struct TorCert {
877    certtype: u8,
879    cert: Vec<u8>,
881}
882fn enc_one_tor_cert<W: Writer + ?Sized>(w: &mut W, c: &TorCert) -> EncodeResult<()> {
884    w.write_u8(c.certtype);
885    let cert_len: u16 = c
886        .cert
887        .len()
888        .try_into()
889        .map_err(|_| EncodeError::BadLengthValue)?;
890    w.write_u16(cert_len);
891    w.write_all(&c.cert[..]);
892    Ok(())
893}
894fn take_one_tor_cert(r: &mut Reader<'_>) -> Result<TorCert> {
896    let certtype = r.take_u8()?;
897    let certlen = r.take_u16()?;
898    let cert = r.take(certlen as usize)?;
899    Ok(TorCert {
900        certtype,
901        cert: cert.into(),
902    })
903}
904#[derive(Clone, Debug, Deftly)]
914#[derive_deftly(HasMemoryCost)]
915pub struct Certs {
916    certs: Vec<TorCert>,
918}
919impl Certs {
920    pub fn new_empty() -> Self {
922        Certs { certs: Vec::new() }
923    }
924    pub fn push_cert_body<B>(&mut self, certtype: tor_cert::CertType, cert: B)
928    where
929        B: Into<Vec<u8>>,
930    {
931        let certtype = certtype.into();
932        let cert = cert.into();
933        self.certs.push(TorCert { certtype, cert });
934    }
935
936    pub fn cert_body(&self, tp: tor_cert::CertType) -> Option<&[u8]> {
938        let tp: u8 = tp.into();
939        self.certs
940            .iter()
941            .find(|c| c.certtype == tp)
942            .map(|c| &c.cert[..])
943    }
944
945    pub fn parse_ed_cert(&self, tp: tor_cert::CertType) -> crate::Result<tor_cert::KeyUnknownCert> {
948        let body = self
949            .cert_body(tp)
950            .ok_or_else(|| crate::Error::ChanProto(format!("Missing {} certificate", tp)))?;
951
952        let cert = tor_cert::Ed25519Cert::decode(body).map_err(|be| crate::Error::BytesErr {
953            err: be,
954            parsed: "ed25519 certificate",
955        })?;
956        if cert.peek_cert_type() != tp {
957            return Err(crate::Error::ChanProto(format!(
958                "Found a {} certificate labeled as {}",
959                cert.peek_cert_type(),
960                tp
961            )));
962        }
963
964        Ok(cert)
965    }
966}
967
968impl Body for Certs {
969    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
970        let n_certs: u8 = self
971            .certs
972            .len()
973            .try_into()
974            .map_err(|_| EncodeError::BadLengthValue)?;
975        w.write_u8(n_certs);
976        for c in &self.certs {
977            enc_one_tor_cert(w, c)?;
978        }
979        Ok(())
980    }
981}
982impl Readable for Certs {
983    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
984        let n = r.take_u8()?;
985        let mut certs = Vec::new();
986        for _ in 0..n {
987            certs.push(take_one_tor_cert(r)?);
988        }
989        Ok(Certs { certs })
990    }
991}
992
993const CHALLENGE_LEN: usize = 32;
995
996#[derive(Clone, Debug, Deftly)]
1005#[derive_deftly(HasMemoryCost)]
1006pub struct AuthChallenge {
1007    challenge: [u8; CHALLENGE_LEN],
1009    methods: Vec<u16>,
1011}
1012impl AuthChallenge {
1013    pub fn new<B, M>(challenge: B, methods: M) -> Self
1016    where
1017        B: Into<[u8; CHALLENGE_LEN]>,
1018        M: Into<Vec<u16>>,
1019    {
1020        AuthChallenge {
1021            challenge: challenge.into(),
1022            methods: methods.into(),
1023        }
1024    }
1025
1026    pub fn methods(&self) -> &[u16] {
1028        &self.methods
1029    }
1030}
1031
1032impl Body for AuthChallenge {
1033    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1034        w.write_all(&self.challenge[..]);
1035        let n_methods = self
1036            .methods
1037            .len()
1038            .try_into()
1039            .map_err(|_| EncodeError::BadLengthValue)?;
1040        w.write_u16(n_methods);
1041        for m in self.methods {
1042            w.write_u16(m);
1043        }
1044        Ok(())
1045    }
1046}
1047impl Readable for AuthChallenge {
1048    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1049        let challenge = r.extract()?;
1051        let n_methods = r.take_u16()?;
1052        let mut methods = Vec::new();
1053        for _ in 0..n_methods {
1054            methods.push(r.take_u16()?);
1055        }
1056        Ok(AuthChallenge { challenge, methods })
1057    }
1058}
1059
1060#[derive(Clone, Debug, Deftly)]
1067#[derive_deftly(HasMemoryCost)]
1068pub struct Authenticate {
1069    authtype: u16,
1071    auth: Vec<u8>,
1073}
1074impl Authenticate {
1075    pub fn new<B>(authtype: u16, body: B) -> Self
1077    where
1078        B: Into<Vec<u8>>,
1079    {
1080        Authenticate {
1081            authtype,
1082            auth: body.into(),
1083        }
1084    }
1085}
1086impl Body for Authenticate {
1087    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1088        w.write_u16(self.authtype);
1089        let authlen = self
1090            .auth
1091            .len()
1092            .try_into()
1093            .map_err(|_| EncodeError::BadLengthValue)?;
1094        w.write_u16(authlen);
1095        w.write_all(&self.auth[..]);
1096        Ok(())
1097    }
1098}
1099impl Readable for Authenticate {
1100    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1101        let authtype = r.take_u16()?;
1102        let authlen = r.take_u16()?;
1103        let auth = r.take(authlen as usize)?.into();
1104        Ok(Authenticate { authtype, auth })
1105    }
1106}
1107
1108#[derive(Clone, Debug, Deftly)]
1116#[derive_deftly(HasMemoryCost)]
1117pub struct Unrecognized {
1118    cmd: ChanCmd,
1120    content: Vec<u8>,
1122}
1123impl Unrecognized {
1124    pub fn new<B>(cmd: ChanCmd, content: B) -> Self
1126    where
1127        B: Into<Vec<u8>>,
1128    {
1129        let content = content.into();
1130        Unrecognized { cmd, content }
1131    }
1132    pub fn cmd(&self) -> ChanCmd {
1134        self.cmd
1135    }
1136    pub fn decode_with_cmd(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Unrecognized> {
1139        let mut u = Unrecognized::take_from(r)?;
1140        u.cmd = cmd;
1141        Ok(u)
1142    }
1143}
1144impl Body for Unrecognized {
1145    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1146        w.write_all(&self.content[..]);
1147        Ok(())
1148    }
1149}
1150impl Readable for Unrecognized {
1151    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1152        Ok(Unrecognized {
1153            cmd: 0.into(),
1154            content: r.take(r.remaining())?.into(),
1155        })
1156    }
1157}
1158
1159macro_rules! msg_into_cell {
1162    ($body:ident) => {
1163        impl From<$body> for super::AnyChanCell {
1164            fn from(body: $body) -> super::AnyChanCell {
1165                super::AnyChanCell {
1166                    circid: None,
1167                    msg: body.into(),
1168                }
1169            }
1170        }
1171    };
1172}
1173
1174msg_into_cell!(Padding);
1175msg_into_cell!(Vpadding);
1176msg_into_cell!(Netinfo);
1177msg_into_cell!(Versions);
1178msg_into_cell!(PaddingNegotiate);
1179msg_into_cell!(Certs);
1180msg_into_cell!(AuthChallenge);
1181msg_into_cell!(Authenticate);
1182
1183macro_rules! msg_impl_chanmsg {
1193    ($($body:ident,)*) =>
1194    {paste::paste!{
1195       $(impl crate::chancell::ChanMsg for $body {
1196            fn cmd(&self) -> crate::chancell::ChanCmd { crate::chancell::ChanCmd::[< $body:snake:upper >] }
1197            fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1198                crate::chancell::msg::Body::encode_onto(self, w)
1199            }
1200            fn decode_from_reader(cmd: ChanCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1201                if cmd != crate::chancell::ChanCmd::[< $body:snake:upper >] {
1202                    return Err(tor_bytes::Error::InvalidMessage(
1203                        format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1204                    ));
1205                }
1206                crate::chancell::msg::Body::decode_from_reader(r)
1207            }
1208        })*
1209    }}
1210}
1211
1212msg_impl_chanmsg!(
1215    Padding,
1216    Vpadding,
1217    Create,
1218    CreateFast,
1219    Create2,
1220    Created,
1221    CreatedFast,
1222    Created2,
1223    Relay,
1224    RelayEarly,
1225    Destroy,
1226    Netinfo,
1227    Versions,
1228    PaddingNegotiate,
1229    Certs,
1230    AuthChallenge,
1231    Authenticate,
1232);
1233
1234#[cfg(test)]
1235mod test {
1236    #![allow(clippy::bool_assert_comparison)]
1238    #![allow(clippy::clone_on_copy)]
1239    #![allow(clippy::dbg_macro)]
1240    #![allow(clippy::mixed_attributes_style)]
1241    #![allow(clippy::print_stderr)]
1242    #![allow(clippy::print_stdout)]
1243    #![allow(clippy::single_char_pattern)]
1244    #![allow(clippy::unwrap_used)]
1245    #![allow(clippy::unchecked_duration_subtraction)]
1246    #![allow(clippy::useless_vec)]
1247    #![allow(clippy::needless_pass_by_value)]
1248    use super::*;
1250    #[test]
1251    fn destroy_reason() {
1252        let r1 = DestroyReason::CONNECTFAILED;
1253
1254        assert_eq!(r1.human_str(), "Couldn't connect to relay");
1255
1256        let r2 = DestroyReason::from(200); assert_eq!(r2.human_str(), "Unrecognized reason");
1258    }
1259}