1use super::{BoxedCellBody, ChanCmd, RawCellBody, CELL_DATA_LEN};
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 Authorize,
78 _ =>
79 Unrecognized,
81}
82}
83
84#[derive(Clone, Debug, Default, Deftly)]
92#[derive_deftly(HasMemoryCost)]
93#[non_exhaustive]
94pub struct Padding {}
95impl Padding {
96 pub fn new() -> Self {
98 Padding {}
99 }
100}
101impl Body for Padding {
102 fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
103 Ok(())
104 }
105}
106impl Readable for Padding {
107 fn take_from(_b: &mut Reader<'_>) -> Result<Self> {
108 Ok(Padding {})
109 }
110}
111
112#[derive(Clone, Debug, Deftly)]
116#[derive_deftly(HasMemoryCost)]
117pub struct Vpadding {
118 len: u16,
120}
121impl Vpadding {
122 pub fn new(len: u16) -> Self {
124 Vpadding { len }
125 }
126}
127impl Body for Vpadding {
128 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
129 w.write_zeros(self.len as usize);
130 Ok(())
131 }
132}
133impl Readable for Vpadding {
134 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
135 if b.remaining() > u16::MAX as usize {
136 return Err(Error::InvalidMessage(
137 "Too many bytes in VPADDING cell".into(),
138 ));
139 }
140 Ok(Vpadding {
141 len: b.remaining() as u16,
142 })
143 }
144}
145
146macro_rules! fixed_len_handshake {
149 {
150 $(#[$meta:meta])*
151 $name:ident , $cmd:ident, $len:ident
152 } => {
153 $(#[$meta])*
154 #[derive(Clone,Debug,Deftly)]
155 #[derive_deftly(HasMemoryCost)]
156 pub struct $name {
157 handshake: Vec<u8>
158 }
159 impl $name {
160 pub fn new<B>(handshake: B) -> Self
162 where B: Into<Vec<u8>>
163 {
164 let handshake = handshake.into();
165 $name { handshake }
166 }
167 }
168 impl Body for $name {
169 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
170 w.write_all(&self.handshake[..]);
171 Ok(())
172 }
173 }
174 impl Readable for $name {
175 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
176 Ok($name {
177 handshake: b.take($len)?.into(),
178 })
179 }
180 }
181 }
182}
183
184pub(crate) const TAP_C_HANDSHAKE_LEN: usize = 128 + 16 + 42;
186pub(crate) const TAP_S_HANDSHAKE_LEN: usize = 128 + 20;
188
189const FAST_C_HANDSHAKE_LEN: usize = 20;
191const FAST_S_HANDSHAKE_LEN: usize = 20 + 20;
193
194fixed_len_handshake! {
195 Create, CREATE, TAP_C_HANDSHAKE_LEN
204}
205fixed_len_handshake! {
206 Created, CREATED, TAP_S_HANDSHAKE_LEN
211}
212fixed_len_handshake! {
213 CreateFast, CREATE_FAST, FAST_C_HANDSHAKE_LEN
225}
226impl CreateFast {
227 pub fn handshake(&self) -> &[u8] {
229 &self.handshake
230 }
231}
232fixed_len_handshake! {
233 CreatedFast, CREATED_FAST, FAST_S_HANDSHAKE_LEN
238}
239impl CreatedFast {
240 pub fn into_handshake(self) -> Vec<u8> {
242 self.handshake
243 }
244}
245
246caret_int! {
247 #[derive(Deftly)]
250 #[derive_deftly(HasMemoryCost)]
251 pub struct HandshakeType(u16) {
252 TAP = 0,
254
255 NTOR = 2,
259 NTOR_V3 = 3,
261 }
262}
263
264#[derive(Clone, Debug, Deftly)]
273#[derive_deftly(HasMemoryCost)]
274pub struct Create2 {
275 handshake_type: HandshakeType,
277 handshake: Vec<u8>,
279}
280impl Body for Create2 {
281 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
282 w.write_u16(self.handshake_type.into());
283 let handshake_len = self
284 .handshake
285 .len()
286 .try_into()
287 .map_err(|_| EncodeError::BadLengthValue)?;
288 w.write_u16(handshake_len);
289 w.write_all(&self.handshake[..]);
290 Ok(())
291 }
292}
293impl Readable for Create2 {
294 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
295 let handshake_type = HandshakeType::from(b.take_u16()?);
296 let hlen = b.take_u16()?;
297 let handshake = b.take(hlen as usize)?.into();
298 Ok(Create2 {
299 handshake_type,
300 handshake,
301 })
302 }
303}
304impl Create2 {
305 pub fn new<B>(handshake_type: HandshakeType, handshake: B) -> Self
307 where
308 B: Into<Vec<u8>>,
309 {
310 let handshake = handshake.into();
311 Create2 {
312 handshake_type,
313 handshake,
314 }
315 }
316
317 pub fn handshake_type(&self) -> HandshakeType {
319 self.handshake_type
320 }
321
322 pub fn body(&self) -> &[u8] {
324 &self.handshake[..]
325 }
326}
327
328#[derive(Clone, Debug, Deftly)]
333#[derive_deftly(HasMemoryCost)]
334pub struct Created2 {
335 handshake: Vec<u8>,
337}
338impl Created2 {
339 pub fn new<B>(handshake: B) -> Self
341 where
342 B: Into<Vec<u8>>,
343 {
344 let handshake = handshake.into();
345 Created2 { handshake }
346 }
347 pub fn into_body(self) -> Vec<u8> {
349 self.handshake
350 }
351}
352impl Body for Created2 {
353 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
354 let handshake_len = self
355 .handshake
356 .len()
357 .try_into()
358 .map_err(|_| EncodeError::BadLengthValue)?;
359 w.write_u16(handshake_len);
360 w.write_all(&self.handshake[..]);
361 Ok(())
362 }
363}
364impl Readable for Created2 {
365 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
366 let hlen = b.take_u16()?;
367 let handshake = b.take(hlen as usize)?.into();
368 Ok(Created2 { handshake })
369 }
370}
371
372#[derive(Clone, Educe, derive_more::From, Deftly)]
383#[derive_deftly(HasMemoryCost)]
384#[educe(Debug)]
385pub struct Relay {
386 #[educe(Debug(method = "skip_fmt"))]
394 body: BoxedCellBody,
395}
396impl Relay {
397 pub fn new<P>(body: P) -> Self
399 where
400 P: AsRef<[u8]>,
401 {
402 let body = body.as_ref();
403 let mut r = [0_u8; CELL_DATA_LEN];
404 r[..body.len()].copy_from_slice(body);
407 Relay { body: Box::new(r) }
408 }
409 pub fn from_raw(body: RawCellBody) -> Self {
411 Relay {
412 body: Box::new(body),
413 }
414 }
415 pub fn into_relay_body(self) -> BoxedCellBody {
418 self.body
419 }
420 pub fn into_early(self) -> AnyChanMsg {
422 AnyChanMsg::RelayEarly(RelayEarly(self))
423 }
424}
425impl Body for Relay {
426 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
427 w.write_all(&self.body[..]);
428 Ok(())
429 }
430}
431impl Readable for Relay {
432 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
433 let mut body = Box::new([0_u8; CELL_DATA_LEN]);
434 body.copy_from_slice(b.take(CELL_DATA_LEN)?);
435 Ok(Relay { body })
436 }
437}
438
439#[derive(Clone, Debug, derive_more::Deref, derive_more::From, derive_more::Into, Deftly)]
443#[derive_deftly(HasMemoryCost)]
444pub struct RelayEarly(Relay);
445impl Readable for RelayEarly {
446 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
447 Ok(RelayEarly(Relay::take_from(r)?))
448 }
449}
450impl Body for RelayEarly {
451 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
452 self.0.encode_onto(w)
453 }
454}
455impl RelayEarly {
456 pub fn into_relay_body(self) -> BoxedCellBody {
462 self.0.body
463 }
464}
465
466#[derive(Clone, Debug, Deftly)]
472#[derive_deftly(HasMemoryCost)]
473pub struct Destroy {
474 reason: DestroyReason,
476}
477impl Destroy {
478 pub fn new(reason: DestroyReason) -> Self {
480 Destroy { reason }
481 }
482 pub fn reason(&self) -> DestroyReason {
484 self.reason
485 }
486}
487impl Body for Destroy {
488 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
489 w.write_u8(self.reason.into());
490 Ok(())
491 }
492}
493impl Readable for Destroy {
494 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
495 let reason = r.take_u8()?.into();
496 Ok(Destroy { reason })
497 }
498}
499
500caret_int! {
501 #[derive(Deftly)]
503 #[derive_deftly(HasMemoryCost)]
504 pub struct DestroyReason(u8) {
505 NONE = 0,
509 PROTOCOL = 1,
511 INTERNAL = 2,
513 REQUESTED = 3,
515 HIBERNATING = 4,
517 RESOURCELIMIT = 5,
519 CONNECTFAILED = 6,
521 OR_IDENTITY = 7,
523 CHANNEL_CLOSED = 8,
525 FINISHED = 9,
527 TIMEOUT = 10,
529 DESTROYED = 11,
531 NOSUCHSERVICE = 12
533 }
534}
535
536impl DestroyReason {
537 pub fn human_str(&self) -> &'static str {
539 match *self {
540 DestroyReason::NONE => "No reason",
541 DestroyReason::PROTOCOL => "Protocol violation",
542 DestroyReason::INTERNAL => "Internal error",
543 DestroyReason::REQUESTED => "Client sent a TRUNCATE command",
544 DestroyReason::HIBERNATING => "Relay is hibernating and not accepting requests",
545 DestroyReason::RESOURCELIMIT => "Relay ran out of resources",
546 DestroyReason::CONNECTFAILED => "Couldn't connect to relay",
547 DestroyReason::OR_IDENTITY => "Connected to relay with different OR identity",
548 DestroyReason::CHANNEL_CLOSED => "The OR channels carrying this circuit died",
549 DestroyReason::FINISHED => "Circuit expired for being too dirty or old",
550 DestroyReason::TIMEOUT => "Circuit construction took too long",
551 DestroyReason::DESTROYED => "Circuit was destroyed without client truncate",
552 DestroyReason::NOSUCHSERVICE => "No such onion service",
553 _ => "Unrecognized reason",
554 }
555 }
556}
557
558#[derive(Clone, Debug, Deftly)]
566#[derive_deftly(HasMemoryCost)]
567pub struct Netinfo {
568 timestamp: u32,
574 their_addr: Option<IpAddr>,
576 my_addr: Vec<IpAddr>,
578}
579fn enc_one_netinfo_addr<W: Writer + ?Sized>(w: &mut W, addr: &IpAddr) {
581 match addr {
582 IpAddr::V4(ipv4) => {
583 w.write_u8(0x04); w.write_u8(4); w.write_all(&ipv4.octets()[..]);
586 }
587 IpAddr::V6(ipv6) => {
588 w.write_u8(0x06); w.write_u8(16); w.write_all(&ipv6.octets()[..]);
591 }
592 }
593}
594fn take_one_netinfo_addr(r: &mut Reader<'_>) -> Result<Option<IpAddr>> {
596 let atype = r.take_u8()?;
597 let alen = r.take_u8()?;
598 let abody = r.take(alen as usize)?;
599 match (atype, alen) {
600 (0x04, 4) => {
601 let bytes = [abody[0], abody[1], abody[2], abody[3]];
602 Ok(Some(IpAddr::V4(bytes.into())))
603 }
604 (0x06, 16) => {
605 let mut bytes = [0_u8; 16];
607 bytes.copy_from_slice(abody);
608 Ok(Some(IpAddr::V6(bytes.into())))
609 }
610 (_, _) => Ok(None),
611 }
612}
613impl Netinfo {
614 pub fn from_client(their_addr: Option<IpAddr>) -> Self {
616 Netinfo {
617 timestamp: 0, their_addr,
619 my_addr: Vec::new(), }
621 }
622 pub fn from_relay<V>(timestamp: u32, their_addr: Option<IpAddr>, my_addrs: V) -> Self
624 where
625 V: Into<Vec<IpAddr>>,
626 {
627 let my_addr = my_addrs.into();
628 Netinfo {
629 timestamp,
630 their_addr,
631 my_addr,
632 }
633 }
634 pub fn timestamp(&self) -> Option<std::time::SystemTime> {
636 use std::time::{Duration, SystemTime};
637 if self.timestamp == 0 {
638 None
639 } else {
640 Some(SystemTime::UNIX_EPOCH + Duration::from_secs(self.timestamp.into()))
641 }
642 }
643}
644impl Body for Netinfo {
645 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
646 w.write_u32(self.timestamp);
647 let their_addr = self
648 .their_addr
649 .unwrap_or_else(|| Ipv4Addr::UNSPECIFIED.into());
650 enc_one_netinfo_addr(w, &their_addr);
651 let n_addrs: u8 = self
652 .my_addr
653 .len()
654 .try_into()
655 .map_err(|_| EncodeError::BadLengthValue)?;
656 w.write_u8(n_addrs);
657 for addr in &self.my_addr {
658 enc_one_netinfo_addr(w, addr);
659 }
660 Ok(())
661 }
662}
663impl Readable for Netinfo {
664 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
665 let timestamp = r.take_u32()?;
666 let their_addr = take_one_netinfo_addr(r)?.filter(|a| !a.is_unspecified());
667 let my_n_addrs = r.take_u8()?;
668 let mut my_addr = Vec::with_capacity(my_n_addrs as usize);
669 for _ in 0..my_n_addrs {
670 if let Some(a) = take_one_netinfo_addr(r)? {
671 my_addr.push(a);
672 }
673 }
674 Ok(Netinfo {
675 timestamp,
676 their_addr,
677 my_addr,
678 })
679 }
680}
681
682#[derive(Clone, Debug, Deftly)]
692#[derive_deftly(HasMemoryCost)]
693pub struct Versions {
694 versions: Vec<u16>,
696}
697impl Versions {
698 pub fn new<B>(vs: B) -> crate::Result<Self>
703 where
704 B: Into<Vec<u16>>,
705 {
706 let versions = vs.into();
707 if versions.len() < (u16::MAX / 2) as usize {
708 Ok(Self { versions })
709 } else {
710 Err(crate::Error::CantEncode("Too many versions"))
711 }
712 }
713 pub fn encode_for_handshake(self) -> EncodeResult<Vec<u8>> {
719 let mut v = Vec::new();
720 v.write_u16(0); v.write_u8(ChanCmd::VERSIONS.into());
722 v.write_u16((self.versions.len() * 2) as u16); self.encode_onto(&mut v)?;
724 Ok(v)
725 }
726 pub fn best_shared_link_protocol(&self, my_protos: &[u16]) -> Option<u16> {
729 let p = my_protos
732 .iter()
733 .filter(|p| self.versions.contains(p))
734 .fold(0_u16, |a, b| u16::max(a, *b));
735 if p == 0 {
736 None
737 } else {
738 Some(p)
739 }
740 }
741}
742impl Body for Versions {
743 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
744 for v in &self.versions {
745 w.write_u16(*v);
746 }
747 Ok(())
748 }
749}
750impl Readable for Versions {
751 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
752 let mut versions = Vec::new();
753 while r.remaining() > 0 {
754 versions.push(r.take_u16()?);
755 }
756 Ok(Versions { versions })
757 }
758}
759
760caret_int! {
761 #[derive(Deftly)]
764 #[derive_deftly(HasMemoryCost)]
765 pub struct PaddingNegotiateCmd(u8) {
766 START = 2,
768
769 STOP = 1,
771 }
772}
773
774#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
786#[derive_deftly(HasMemoryCost)]
787pub struct PaddingNegotiate {
788 command: PaddingNegotiateCmd,
790 ito_low_ms: u16,
793 ito_high_ms: u16,
796}
797impl PaddingNegotiate {
798 pub fn start_default() -> Self {
802 Self {
804 command: PaddingNegotiateCmd::START,
805 ito_low_ms: 0,
806 ito_high_ms: 0,
807 }
808 }
809
810 pub fn start(ito_low: IntegerMilliseconds<u16>, ito_high: IntegerMilliseconds<u16>) -> Self {
812 Self {
814 command: PaddingNegotiateCmd::START,
815 ito_low_ms: ito_low.as_millis(),
816 ito_high_ms: ito_high.as_millis(),
817 }
818 }
819
820 pub fn stop() -> Self {
822 Self {
824 command: PaddingNegotiateCmd::STOP,
825 ito_low_ms: 0,
826 ito_high_ms: 0,
827 }
828 }
829
830 #[cfg(feature = "testing")]
834 pub fn from_raw(command: PaddingNegotiateCmd, ito_low_ms: u16, ito_high_ms: u16) -> Self {
835 PaddingNegotiate {
836 command,
837 ito_low_ms,
838 ito_high_ms,
839 }
840 }
841}
842impl Default for PaddingNegotiate {
843 fn default() -> Self {
844 Self::start_default()
845 }
846}
847
848impl Body for PaddingNegotiate {
849 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
850 w.write_u8(0); w.write_u8(self.command.get());
852 w.write_u16(self.ito_low_ms);
853 w.write_u16(self.ito_high_ms);
854 Ok(())
855 }
856}
857impl Readable for PaddingNegotiate {
858 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
859 let v = r.take_u8()?;
860 if v != 0 {
861 return Err(Error::InvalidMessage(
862 "Unrecognized padding negotiation version".into(),
863 ));
864 }
865 let command = r.take_u8()?.into();
866 let ito_low_ms = r.take_u16()?;
867 let ito_high_ms = r.take_u16()?;
868 Ok(PaddingNegotiate {
869 command,
870 ito_low_ms,
871 ito_high_ms,
872 })
873 }
874}
875
876#[derive(Clone, Debug, Deftly)]
881#[derive_deftly(HasMemoryCost)]
882struct TorCert {
883 certtype: u8,
885 cert: Vec<u8>,
887}
888fn enc_one_tor_cert<W: Writer + ?Sized>(w: &mut W, c: &TorCert) -> EncodeResult<()> {
890 w.write_u8(c.certtype);
891 let cert_len: u16 = c
892 .cert
893 .len()
894 .try_into()
895 .map_err(|_| EncodeError::BadLengthValue)?;
896 w.write_u16(cert_len);
897 w.write_all(&c.cert[..]);
898 Ok(())
899}
900fn take_one_tor_cert(r: &mut Reader<'_>) -> Result<TorCert> {
902 let certtype = r.take_u8()?;
903 let certlen = r.take_u16()?;
904 let cert = r.take(certlen as usize)?;
905 Ok(TorCert {
906 certtype,
907 cert: cert.into(),
908 })
909}
910#[derive(Clone, Debug, Deftly)]
920#[derive_deftly(HasMemoryCost)]
921pub struct Certs {
922 certs: Vec<TorCert>,
924}
925impl Certs {
926 pub fn new_empty() -> Self {
928 Certs { certs: Vec::new() }
929 }
930 pub fn push_cert_body<B>(&mut self, certtype: tor_cert::CertType, cert: B)
934 where
935 B: Into<Vec<u8>>,
936 {
937 let certtype = certtype.into();
938 let cert = cert.into();
939 self.certs.push(TorCert { certtype, cert });
940 }
941
942 pub fn cert_body(&self, tp: tor_cert::CertType) -> Option<&[u8]> {
944 let tp: u8 = tp.into();
945 self.certs
946 .iter()
947 .find(|c| c.certtype == tp)
948 .map(|c| &c.cert[..])
949 }
950
951 pub fn parse_ed_cert(&self, tp: tor_cert::CertType) -> crate::Result<tor_cert::KeyUnknownCert> {
954 let body = self
955 .cert_body(tp)
956 .ok_or_else(|| crate::Error::ChanProto(format!("Missing {} certificate", tp)))?;
957
958 let cert = tor_cert::Ed25519Cert::decode(body).map_err(|be| crate::Error::BytesErr {
959 err: be,
960 parsed: "ed25519 certificate",
961 })?;
962 if cert.peek_cert_type() != tp {
963 return Err(crate::Error::ChanProto(format!(
964 "Found a {} certificate labeled as {}",
965 cert.peek_cert_type(),
966 tp
967 )));
968 }
969
970 Ok(cert)
971 }
972}
973
974impl Body for Certs {
975 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
976 let n_certs: u8 = self
977 .certs
978 .len()
979 .try_into()
980 .map_err(|_| EncodeError::BadLengthValue)?;
981 w.write_u8(n_certs);
982 for c in &self.certs {
983 enc_one_tor_cert(w, c)?;
984 }
985 Ok(())
986 }
987}
988impl Readable for Certs {
989 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
990 let n = r.take_u8()?;
991 let mut certs = Vec::new();
992 for _ in 0..n {
993 certs.push(take_one_tor_cert(r)?);
994 }
995 Ok(Certs { certs })
996 }
997}
998
999const CHALLENGE_LEN: usize = 32;
1001
1002#[derive(Clone, Debug, Deftly)]
1011#[derive_deftly(HasMemoryCost)]
1012pub struct AuthChallenge {
1013 challenge: [u8; CHALLENGE_LEN],
1015 methods: Vec<u16>,
1017}
1018impl AuthChallenge {
1019 pub fn new<B, M>(challenge: B, methods: M) -> Self
1022 where
1023 B: Into<[u8; CHALLENGE_LEN]>,
1024 M: Into<Vec<u16>>,
1025 {
1026 AuthChallenge {
1027 challenge: challenge.into(),
1028 methods: methods.into(),
1029 }
1030 }
1031}
1032
1033impl Body for AuthChallenge {
1034 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1035 w.write_all(&self.challenge[..]);
1036 let n_methods = self
1037 .methods
1038 .len()
1039 .try_into()
1040 .map_err(|_| EncodeError::BadLengthValue)?;
1041 w.write_u16(n_methods);
1042 for m in self.methods {
1043 w.write_u16(m);
1044 }
1045 Ok(())
1046 }
1047}
1048impl Readable for AuthChallenge {
1049 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1050 let challenge = r.extract()?;
1052 let n_methods = r.take_u16()?;
1053 let mut methods = Vec::new();
1054 for _ in 0..n_methods {
1055 methods.push(r.take_u16()?);
1056 }
1057 Ok(AuthChallenge { challenge, methods })
1058 }
1059}
1060
1061#[derive(Clone, Debug, Deftly)]
1068#[derive_deftly(HasMemoryCost)]
1069pub struct Authenticate {
1070 authtype: u16,
1072 auth: Vec<u8>,
1074}
1075impl Authenticate {
1076 pub fn new<B>(authtype: u16, body: B) -> Self
1078 where
1079 B: Into<Vec<u8>>,
1080 {
1081 Authenticate {
1082 authtype,
1083 auth: body.into(),
1084 }
1085 }
1086}
1087impl Body for Authenticate {
1088 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1089 w.write_u16(self.authtype);
1090 let authlen = self
1091 .auth
1092 .len()
1093 .try_into()
1094 .map_err(|_| EncodeError::BadLengthValue)?;
1095 w.write_u16(authlen);
1096 w.write_all(&self.auth[..]);
1097 Ok(())
1098 }
1099}
1100impl Readable for Authenticate {
1101 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1102 let authtype = r.take_u16()?;
1103 let authlen = r.take_u16()?;
1104 let auth = r.take(authlen as usize)?.into();
1105 Ok(Authenticate { authtype, auth })
1106 }
1107}
1108
1109#[derive(Clone, Debug, Deftly)]
1111#[derive_deftly(HasMemoryCost)]
1112pub struct Authorize {
1113 content: Vec<u8>,
1115}
1116impl Authorize {
1117 pub fn new<B>(content: B) -> Self
1119 where
1120 B: Into<Vec<u8>>,
1121 {
1122 let content = content.into();
1123 Authorize { content }
1124 }
1125}
1126impl Body for Authorize {
1127 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1128 w.write_all(&self.content[..]);
1129 Ok(())
1130 }
1131}
1132impl Readable for Authorize {
1133 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1134 Ok(Authorize {
1135 content: r.take(r.remaining())?.into(),
1136 })
1137 }
1138}
1139
1140#[derive(Clone, Debug, Deftly)]
1148#[derive_deftly(HasMemoryCost)]
1149pub struct Unrecognized {
1150 cmd: ChanCmd,
1152 content: Vec<u8>,
1154}
1155impl Unrecognized {
1156 pub fn new<B>(cmd: ChanCmd, content: B) -> Self
1158 where
1159 B: Into<Vec<u8>>,
1160 {
1161 let content = content.into();
1162 Unrecognized { cmd, content }
1163 }
1164 pub fn cmd(&self) -> ChanCmd {
1166 self.cmd
1167 }
1168 pub fn decode_with_cmd(cmd: ChanCmd, r: &mut Reader<'_>) -> Result<Unrecognized> {
1171 let mut u = Unrecognized::take_from(r)?;
1172 u.cmd = cmd;
1173 Ok(u)
1174 }
1175}
1176impl Body for Unrecognized {
1177 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1178 w.write_all(&self.content[..]);
1179 Ok(())
1180 }
1181}
1182impl Readable for Unrecognized {
1183 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1184 Ok(Unrecognized {
1185 cmd: 0.into(),
1186 content: r.take(r.remaining())?.into(),
1187 })
1188 }
1189}
1190
1191macro_rules! msg_into_cell {
1194 ($body:ident) => {
1195 impl From<$body> for super::AnyChanCell {
1196 fn from(body: $body) -> super::AnyChanCell {
1197 super::AnyChanCell {
1198 circid: None,
1199 msg: body.into(),
1200 }
1201 }
1202 }
1203 };
1204}
1205
1206msg_into_cell!(Padding);
1207msg_into_cell!(Vpadding);
1208msg_into_cell!(Netinfo);
1209msg_into_cell!(Versions);
1210msg_into_cell!(PaddingNegotiate);
1211msg_into_cell!(Certs);
1212msg_into_cell!(AuthChallenge);
1213msg_into_cell!(Authenticate);
1214msg_into_cell!(Authorize);
1215
1216macro_rules! msg_impl_chanmsg {
1226 ($($body:ident,)*) =>
1227 {paste::paste!{
1228 $(impl crate::chancell::ChanMsg for $body {
1229 fn cmd(&self) -> crate::chancell::ChanCmd { crate::chancell::ChanCmd::[< $body:snake:upper >] }
1230 fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1231 crate::chancell::msg::Body::encode_onto(self, w)
1232 }
1233 fn decode_from_reader(cmd: ChanCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1234 if cmd != crate::chancell::ChanCmd::[< $body:snake:upper >] {
1235 return Err(tor_bytes::Error::InvalidMessage(
1236 format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1237 ));
1238 }
1239 crate::chancell::msg::Body::decode_from_reader(r)
1240 }
1241 })*
1242 }}
1243}
1244
1245msg_impl_chanmsg!(
1248 Padding,
1249 Vpadding,
1250 Create,
1251 CreateFast,
1252 Create2,
1253 Created,
1254 CreatedFast,
1255 Created2,
1256 Relay,
1257 RelayEarly,
1258 Destroy,
1259 Netinfo,
1260 Versions,
1261 PaddingNegotiate,
1262 Certs,
1263 AuthChallenge,
1264 Authenticate,
1265 Authorize,
1266);
1267
1268#[cfg(test)]
1269mod test {
1270 #![allow(clippy::bool_assert_comparison)]
1272 #![allow(clippy::clone_on_copy)]
1273 #![allow(clippy::dbg_macro)]
1274 #![allow(clippy::mixed_attributes_style)]
1275 #![allow(clippy::print_stderr)]
1276 #![allow(clippy::print_stdout)]
1277 #![allow(clippy::single_char_pattern)]
1278 #![allow(clippy::unwrap_used)]
1279 #![allow(clippy::unchecked_duration_subtraction)]
1280 #![allow(clippy::useless_vec)]
1281 #![allow(clippy::needless_pass_by_value)]
1282 use super::*;
1284 #[test]
1285 fn destroy_reason() {
1286 let r1 = DestroyReason::CONNECTFAILED;
1287
1288 assert_eq!(r1.human_str(), "Couldn't connect to relay");
1289
1290 let r2 = DestroyReason::from(200); assert_eq!(r2.human_str(), "Unrecognized reason");
1292 }
1293}