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
642 pub fn their_addr(&self) -> Option<&IpAddr> {
646 self.their_addr.as_ref()
647 }
648
649 pub fn my_addrs(&self) -> &[IpAddr] {
651 &self.my_addr
652 }
653}
654impl Body for Netinfo {
655 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
656 w.write_u32(self.timestamp);
657 let their_addr = self
658 .their_addr
659 .unwrap_or_else(|| Ipv4Addr::UNSPECIFIED.into());
660 enc_one_netinfo_addr(w, &their_addr);
661 let n_addrs: u8 = self
662 .my_addr
663 .len()
664 .try_into()
665 .map_err(|_| EncodeError::BadLengthValue)?;
666 w.write_u8(n_addrs);
667 for addr in &self.my_addr {
668 enc_one_netinfo_addr(w, addr);
669 }
670 Ok(())
671 }
672}
673impl Readable for Netinfo {
674 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
675 let timestamp = r.take_u32()?;
676 let their_addr = take_one_netinfo_addr(r)?.filter(|a| !a.is_unspecified());
677 let my_n_addrs = r.take_u8()?;
678 let mut my_addr = Vec::with_capacity(my_n_addrs as usize);
679 for _ in 0..my_n_addrs {
680 if let Some(a) = take_one_netinfo_addr(r)? {
681 my_addr.push(a);
682 }
683 }
684 Ok(Netinfo {
685 timestamp,
686 their_addr,
687 my_addr,
688 })
689 }
690}
691
692#[derive(Clone, Debug, Deftly)]
702#[derive_deftly(HasMemoryCost)]
703pub struct Versions {
704 versions: Vec<u16>,
706}
707impl Versions {
708 pub fn new<B>(vs: B) -> crate::Result<Self>
713 where
714 B: Into<Vec<u16>>,
715 {
716 let versions = vs.into();
717 if versions.len() < (u16::MAX / 2) as usize {
718 Ok(Self { versions })
719 } else {
720 Err(crate::Error::CantEncode("Too many versions"))
721 }
722 }
723 pub fn encode_for_handshake(self) -> EncodeResult<Vec<u8>> {
729 let mut v = Vec::new();
730 v.write_u16(0); v.write_u8(ChanCmd::VERSIONS.into());
732 v.write_u16((self.versions.len() * 2) as u16); self.encode_onto(&mut v)?;
734 Ok(v)
735 }
736 pub fn best_shared_link_protocol(&self, my_protos: &[u16]) -> Option<u16> {
739 let p = my_protos
742 .iter()
743 .filter(|p| self.versions.contains(p))
744 .fold(0_u16, |a, b| u16::max(a, *b));
745 if p == 0 { None } else { Some(p) }
746 }
747}
748impl Body for Versions {
749 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
750 for v in &self.versions {
751 w.write_u16(*v);
752 }
753 Ok(())
754 }
755}
756impl Readable for Versions {
757 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
758 let mut versions = Vec::new();
759 while r.remaining() > 0 {
760 versions.push(r.take_u16()?);
761 }
762 Ok(Versions { versions })
763 }
764}
765
766caret_int! {
767 #[derive(Deftly)]
770 #[derive_deftly(HasMemoryCost)]
771 pub struct PaddingNegotiateCmd(u8) {
772 START = 2,
774
775 STOP = 1,
777 }
778}
779
780#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
792#[derive_deftly(HasMemoryCost)]
793pub struct PaddingNegotiate {
794 command: PaddingNegotiateCmd,
796 ito_low_ms: u16,
799 ito_high_ms: u16,
802}
803impl PaddingNegotiate {
804 pub fn start_default() -> Self {
808 Self {
810 command: PaddingNegotiateCmd::START,
811 ito_low_ms: 0,
812 ito_high_ms: 0,
813 }
814 }
815
816 pub fn start(ito_low: IntegerMilliseconds<u16>, ito_high: IntegerMilliseconds<u16>) -> Self {
818 Self {
820 command: PaddingNegotiateCmd::START,
821 ito_low_ms: ito_low.as_millis(),
822 ito_high_ms: ito_high.as_millis(),
823 }
824 }
825
826 pub fn stop() -> Self {
828 Self {
830 command: PaddingNegotiateCmd::STOP,
831 ito_low_ms: 0,
832 ito_high_ms: 0,
833 }
834 }
835
836 #[cfg(feature = "testing")]
840 pub fn from_raw(command: PaddingNegotiateCmd, ito_low_ms: u16, ito_high_ms: u16) -> Self {
841 PaddingNegotiate {
842 command,
843 ito_low_ms,
844 ito_high_ms,
845 }
846 }
847}
848impl Default for PaddingNegotiate {
849 fn default() -> Self {
850 Self::start_default()
851 }
852}
853
854impl Body for PaddingNegotiate {
855 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
856 w.write_u8(0); w.write_u8(self.command.get());
858 w.write_u16(self.ito_low_ms);
859 w.write_u16(self.ito_high_ms);
860 Ok(())
861 }
862}
863impl Readable for PaddingNegotiate {
864 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
865 let v = r.take_u8()?;
866 if v != 0 {
867 return Err(Error::InvalidMessage(
868 "Unrecognized padding negotiation version".into(),
869 ));
870 }
871 let command = r.take_u8()?.into();
872 let ito_low_ms = r.take_u16()?;
873 let ito_high_ms = r.take_u16()?;
874 Ok(PaddingNegotiate {
875 command,
876 ito_low_ms,
877 ito_high_ms,
878 })
879 }
880}
881
882#[derive(Clone, Debug, Deftly)]
887#[derive_deftly(HasMemoryCost)]
888struct TorCert {
889 certtype: u8,
891 cert: Vec<u8>,
893}
894fn enc_one_tor_cert<W: Writer + ?Sized>(w: &mut W, c: &TorCert) -> EncodeResult<()> {
896 w.write_u8(c.certtype);
897 let cert_len: u16 = c
898 .cert
899 .len()
900 .try_into()
901 .map_err(|_| EncodeError::BadLengthValue)?;
902 w.write_u16(cert_len);
903 w.write_all(&c.cert[..]);
904 Ok(())
905}
906fn take_one_tor_cert(r: &mut Reader<'_>) -> Result<TorCert> {
908 let certtype = r.take_u8()?;
909 let certlen = r.take_u16()?;
910 let cert = r.take(certlen as usize)?;
911 Ok(TorCert {
912 certtype,
913 cert: cert.into(),
914 })
915}
916#[derive(Clone, Debug, Deftly)]
926#[derive_deftly(HasMemoryCost)]
927pub struct Certs {
928 certs: Vec<TorCert>,
930}
931impl Certs {
932 pub fn new_empty() -> Self {
934 Certs { certs: Vec::new() }
935 }
936 pub fn push_cert_body<B>(&mut self, certtype: tor_cert::CertType, cert: B)
940 where
941 B: Into<Vec<u8>>,
942 {
943 let certtype = certtype.into();
944 let cert = cert.into();
945 self.certs.push(TorCert { certtype, cert });
946 }
947
948 pub fn cert_body(&self, tp: tor_cert::CertType) -> Option<&[u8]> {
950 let tp: u8 = tp.into();
951 self.certs
952 .iter()
953 .find(|c| c.certtype == tp)
954 .map(|c| &c.cert[..])
955 }
956
957 pub fn parse_ed_cert(&self, tp: tor_cert::CertType) -> crate::Result<tor_cert::KeyUnknownCert> {
960 let body = self
961 .cert_body(tp)
962 .ok_or_else(|| crate::Error::ChanProto(format!("Missing {} certificate", tp)))?;
963
964 let cert = tor_cert::Ed25519Cert::decode(body).map_err(|be| crate::Error::BytesErr {
965 err: be,
966 parsed: "ed25519 certificate",
967 })?;
968 if cert.peek_cert_type() != tp {
969 return Err(crate::Error::ChanProto(format!(
970 "Found a {} certificate labeled as {}",
971 cert.peek_cert_type(),
972 tp
973 )));
974 }
975
976 Ok(cert)
977 }
978}
979
980impl Body for Certs {
981 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
982 let n_certs: u8 = self
983 .certs
984 .len()
985 .try_into()
986 .map_err(|_| EncodeError::BadLengthValue)?;
987 w.write_u8(n_certs);
988 for c in &self.certs {
989 enc_one_tor_cert(w, c)?;
990 }
991 Ok(())
992 }
993}
994impl Readable for Certs {
995 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
996 let n = r.take_u8()?;
997 let mut certs = Vec::new();
998 for _ in 0..n {
999 certs.push(take_one_tor_cert(r)?);
1000 }
1001 Ok(Certs { certs })
1002 }
1003}
1004
1005const CHALLENGE_LEN: usize = 32;
1007
1008#[derive(Clone, Debug, Deftly)]
1017#[derive_deftly(HasMemoryCost)]
1018pub struct AuthChallenge {
1019 challenge: [u8; CHALLENGE_LEN],
1021 methods: Vec<u16>,
1023}
1024impl AuthChallenge {
1025 pub fn new<B, M>(challenge: B, methods: M) -> Self
1028 where
1029 B: Into<[u8; CHALLENGE_LEN]>,
1030 M: Into<Vec<u16>>,
1031 {
1032 AuthChallenge {
1033 challenge: challenge.into(),
1034 methods: methods.into(),
1035 }
1036 }
1037
1038 pub fn methods(&self) -> &[u16] {
1040 &self.methods
1041 }
1042}
1043
1044impl Body for AuthChallenge {
1045 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1046 w.write_all(&self.challenge[..]);
1047 let n_methods = self
1048 .methods
1049 .len()
1050 .try_into()
1051 .map_err(|_| EncodeError::BadLengthValue)?;
1052 w.write_u16(n_methods);
1053 for m in self.methods {
1054 w.write_u16(m);
1055 }
1056 Ok(())
1057 }
1058}
1059impl Readable for AuthChallenge {
1060 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1061 let challenge = r.extract()?;
1063 let n_methods = r.take_u16()?;
1064 let mut methods = Vec::new();
1065 for _ in 0..n_methods {
1066 methods.push(r.take_u16()?);
1067 }
1068 Ok(AuthChallenge { challenge, methods })
1069 }
1070}
1071
1072#[derive(Clone, Debug, Deftly, Eq, PartialEq)]
1079#[derive_deftly(HasMemoryCost)]
1080pub struct Authenticate {
1081 authtype: u16,
1083 auth: Vec<u8>,
1085}
1086impl Authenticate {
1087 pub fn new<B>(authtype: u16, body: B) -> Self
1089 where
1090 B: Into<Vec<u8>>,
1091 {
1092 Authenticate {
1093 authtype,
1094 auth: body.into(),
1095 }
1096 }
1097}
1098impl Body for Authenticate {
1099 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1100 w.write_u16(self.authtype);
1101 let authlen = self
1102 .auth
1103 .len()
1104 .try_into()
1105 .map_err(|_| EncodeError::BadLengthValue)?;
1106 w.write_u16(authlen);
1107 w.write_all(&self.auth[..]);
1108 Ok(())
1109 }
1110}
1111impl Readable for Authenticate {
1112 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1113 let authtype = r.take_u16()?;
1114 let authlen = r.take_u16()?;
1115 let auth = r.take(authlen as usize)?.into();
1116 Ok(Authenticate { authtype, auth })
1117 }
1118}
1119
1120#[derive(Clone, Debug, Deftly)]
1128#[derive_deftly(HasMemoryCost)]
1129pub struct Unrecognized {
1130 cmd: ChanCmd,
1132 content: Vec<u8>,
1134}
1135impl Unrecognized {
1136 pub fn new<B>(cmd: ChanCmd, content: B) -> Self
1138 where
1139 B: Into<Vec<u8>>,
1140 {
1141 let content = content.into();
1142 Unrecognized { cmd, content }
1143 }
1144 pub fn cmd(&self) -> ChanCmd {
1146 self.cmd
1147 }
1148 pub fn decode_with_cmd(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Unrecognized> {
1151 let mut u = Unrecognized::take_from(r)?;
1152 u.cmd = cmd;
1153 Ok(u)
1154 }
1155}
1156impl Body for Unrecognized {
1157 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1158 w.write_all(&self.content[..]);
1159 Ok(())
1160 }
1161}
1162impl Readable for Unrecognized {
1163 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1164 Ok(Unrecognized {
1165 cmd: 0.into(),
1166 content: r.take(r.remaining())?.into(),
1167 })
1168 }
1169}
1170
1171macro_rules! msg_into_cell {
1174 ($body:ident) => {
1175 impl From<$body> for super::AnyChanCell {
1176 fn from(body: $body) -> super::AnyChanCell {
1177 super::AnyChanCell {
1178 circid: None,
1179 msg: body.into(),
1180 }
1181 }
1182 }
1183 };
1184}
1185
1186msg_into_cell!(Padding);
1187msg_into_cell!(Vpadding);
1188msg_into_cell!(Netinfo);
1189msg_into_cell!(Versions);
1190msg_into_cell!(PaddingNegotiate);
1191msg_into_cell!(Certs);
1192msg_into_cell!(AuthChallenge);
1193msg_into_cell!(Authenticate);
1194
1195macro_rules! msg_impl_chanmsg {
1205 ($($body:ident,)*) =>
1206 {paste::paste!{
1207 $(impl crate::chancell::ChanMsg for $body {
1208 fn cmd(&self) -> crate::chancell::ChanCmd { crate::chancell::ChanCmd::[< $body:snake:upper >] }
1209 fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1210 crate::chancell::msg::Body::encode_onto(self, w)
1211 }
1212 fn decode_from_reader(cmd: ChanCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1213 if cmd != crate::chancell::ChanCmd::[< $body:snake:upper >] {
1214 return Err(tor_bytes::Error::InvalidMessage(
1215 format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1216 ));
1217 }
1218 crate::chancell::msg::Body::decode_from_reader(r)
1219 }
1220 })*
1221 }}
1222}
1223
1224msg_impl_chanmsg!(
1227 Padding,
1228 Vpadding,
1229 Create,
1230 CreateFast,
1231 Create2,
1232 Created,
1233 CreatedFast,
1234 Created2,
1235 Relay,
1236 RelayEarly,
1237 Destroy,
1238 Netinfo,
1239 Versions,
1240 PaddingNegotiate,
1241 Certs,
1242 AuthChallenge,
1243 Authenticate,
1244);
1245
1246#[cfg(test)]
1247mod test {
1248 #![allow(clippy::bool_assert_comparison)]
1250 #![allow(clippy::clone_on_copy)]
1251 #![allow(clippy::dbg_macro)]
1252 #![allow(clippy::mixed_attributes_style)]
1253 #![allow(clippy::print_stderr)]
1254 #![allow(clippy::print_stdout)]
1255 #![allow(clippy::single_char_pattern)]
1256 #![allow(clippy::unwrap_used)]
1257 #![allow(clippy::unchecked_time_subtraction)]
1258 #![allow(clippy::useless_vec)]
1259 #![allow(clippy::needless_pass_by_value)]
1260 use super::*;
1262 #[test]
1263 fn destroy_reason() {
1264 let r1 = DestroyReason::CONNECTFAILED;
1265
1266 assert_eq!(r1.human_str(), "Couldn't connect to relay");
1267
1268 let r2 = DestroyReason::from(200); assert_eq!(r2.human_str(), "Unrecognized reason");
1270 }
1271}