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, Eq, PartialEq)]
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_time_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}