1use super::{RelayCellFormat, RelayCmd};
7use crate::chancell::msg::{
8 DestroyReason, HandshakeType, TAP_C_HANDSHAKE_LEN, TAP_S_HANDSHAKE_LEN,
9};
10use crate::chancell::CELL_DATA_LEN;
11use caret::caret_int;
12use derive_deftly::Deftly;
13use std::fmt::Write;
14use std::net::{IpAddr, Ipv4Addr};
15use std::num::NonZeroU8;
16use tor_bytes::{EncodeError, EncodeResult, Error, Result};
17use tor_bytes::{Readable, Reader, Writeable, Writer};
18use tor_linkspec::EncodedLinkSpec;
19use tor_llcrypto::pk::rsa::RsaIdentity;
20use tor_llcrypto::util::ct::CtByteArray;
21use tor_memquota::{derive_deftly_template_HasMemoryCost, memory_cost_structural_copy};
22
23use bitflags::bitflags;
24
25#[cfg(feature = "conflux")]
26#[cfg_attr(docsrs, doc(cfg(feature = "conflux")))]
27pub use super::conflux::{ConfluxLink, ConfluxLinked, ConfluxLinkedAck, ConfluxSwitch};
28
29#[cfg(feature = "flowctl-cc")]
30#[cfg_attr(docsrs, doc(cfg(feature = "flowctl-cc")))]
31use super::flow_ctrl::{Xoff, Xon};
32
33#[cfg(feature = "hs")]
34#[cfg_attr(docsrs, doc(cfg(feature = "hs")))]
35pub use super::hs::{
36 est_intro::EstablishIntro, EstablishRendezvous, IntroEstablished, Introduce1, Introduce2,
37 IntroduceAck, Rendezvous1, Rendezvous2, RendezvousEstablished,
38};
39#[cfg(feature = "experimental-udp")]
40#[cfg_attr(docsrs, doc(cfg(feature = "experimental-udp")))]
41pub use super::udp::{ConnectUdp, ConnectedUdp, Datagram};
42
43crate::restrict::restricted_msg! {
44#[derive(Debug, Clone, Deftly)]
46#[derive_deftly(HasMemoryCost)]
47#[non_exhaustive]
48@omit_from "avoid_conflict_with_a_blanket_implementation"
49pub enum AnyRelayMsg : RelayMsg {
50 Begin,
52 Data,
54 End,
56 Connected,
58 Sendme,
60 Extend,
62 Extended,
64 Extend2,
66 Extended2,
68 Truncate,
70 Truncated,
72 Drop,
74 Resolve,
76 Resolved,
78 BeginDir,
80 [feature = "experimental-udp"]
82 ConnectUdp,
83 [feature = "experimental-udp"]
85 ConnectedUdp,
86 [feature = "experimental-udp"]
88 Datagram,
89 [feature = "conflux"]
91 ConfluxLink,
92 [feature = "conflux"]
94 ConfluxLinked,
95 [feature = "conflux"]
97 ConfluxLinkedAck,
98 [feature = "conflux"]
100 ConfluxSwitch,
101 [feature = "flowctl-cc"]
103 Xon,
104 [feature = "flowctl-cc"]
106 Xoff,
107 [feature = "hs"]
109 EstablishIntro,
110 [feature = "hs"]
112 EstablishRendezvous,
113 [feature = "hs"]
115 Introduce1,
116 [feature = "hs"]
118 Introduce2,
119 [feature = "hs"]
121 Rendezvous1,
122 [feature = "hs"]
124 Rendezvous2,
125 [feature = "hs"]
127 IntroEstablished,
128 [feature = "hs"]
130 RendezvousEstablished,
131 [feature = "hs"]
133 IntroduceAck,
134
135 _ =>
136 Unrecognized,
138 }
139}
140
141pub trait Body: Sized {
143 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self>;
145 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()>;
147}
148
149bitflags! {
150 #[derive(Clone, Copy, Debug)]
155 pub struct BeginFlags : u32 {
156 const IPV6_OKAY = (1<<0);
158 const IPV4_NOT_OKAY = (1<<1);
160 const IPV6_PREFERRED = (1<<2);
162 }
163}
164memory_cost_structural_copy!(BeginFlags);
165impl From<u32> for BeginFlags {
166 fn from(v: u32) -> Self {
167 BeginFlags::from_bits_truncate(v)
168 }
169}
170
171#[derive(Clone, Default, Copy, Debug, Eq, PartialEq)]
174#[non_exhaustive]
175pub enum IpVersionPreference {
176 Ipv4Only,
178 #[default]
180 Ipv4Preferred,
181 Ipv6Preferred,
183 Ipv6Only,
185}
186impl From<IpVersionPreference> for BeginFlags {
187 fn from(v: IpVersionPreference) -> Self {
188 use IpVersionPreference::*;
189 match v {
190 Ipv4Only => 0.into(),
191 Ipv4Preferred => BeginFlags::IPV6_OKAY,
192 Ipv6Preferred => BeginFlags::IPV6_OKAY | BeginFlags::IPV6_PREFERRED,
193 Ipv6Only => BeginFlags::IPV4_NOT_OKAY,
194 }
195 }
196}
197
198#[derive(Debug, Clone, Deftly)]
209#[derive_deftly(HasMemoryCost)]
210pub struct Begin {
211 addr: Vec<u8>,
213 port: u16,
215 flags: BeginFlags,
217}
218
219impl Begin {
220 pub fn new<F>(addr: &str, port: u16, flags: F) -> crate::Result<Self>
222 where
223 F: Into<BeginFlags>,
224 {
225 if !addr.is_ascii() {
226 return Err(crate::Error::BadStreamAddress);
227 }
228 let mut addr = addr.to_string();
229 addr.make_ascii_lowercase();
230 Ok(Begin {
231 addr: addr.into_bytes(),
232 port,
233 flags: flags.into(),
234 })
235 }
236
237 pub fn addr(&self) -> &[u8] {
239 &self.addr[..]
240 }
241
242 pub fn port(&self) -> u16 {
244 self.port
245 }
246
247 pub fn flags(&self) -> BeginFlags {
249 self.flags
250 }
251}
252
253impl Body for Begin {
254 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
255 let addr = {
256 if r.peek(1)? == b"[" {
257 r.advance(1)?;
259 let a = r.take_until(b']')?;
260 let colon = r.take_u8()?;
261 if colon != b':' {
262 return Err(Error::InvalidMessage("missing port in begin cell".into()));
263 }
264 a
265 } else {
266 r.take_until(b':')?
268 }
269 };
270 let port = r.take_until(0)?;
271 let flags = if r.remaining() >= 4 { r.take_u32()? } else { 0 };
272
273 if !addr.is_ascii() {
274 return Err(Error::InvalidMessage(
275 "target address in begin cell not ascii".into(),
276 ));
277 }
278
279 let port = std::str::from_utf8(port)
280 .map_err(|_| Error::InvalidMessage("port in begin cell not utf8".into()))?;
281
282 let port = port
283 .parse()
284 .map_err(|_| Error::InvalidMessage("port in begin cell not a valid port".into()))?;
285
286 Ok(Begin {
287 addr: addr.into(),
288 port,
289 flags: flags.into(),
290 })
291 }
292 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
293 if self.addr.contains(&b':') {
294 w.write_u8(b'[');
295 w.write_all(&self.addr[..]);
296 w.write_u8(b']');
297 } else {
298 w.write_all(&self.addr[..]);
299 }
300 w.write_u8(b':');
301 w.write_all(self.port.to_string().as_bytes());
302 w.write_u8(0);
303 if self.flags.bits() != 0 {
304 w.write_u32(self.flags.bits());
305 }
306 Ok(())
307 }
308}
309
310#[derive(Debug, Clone, Deftly)]
318#[derive_deftly(HasMemoryCost)]
319pub struct Data {
320 body: Vec<u8>,
329}
330impl Data {
331 pub const MAXLEN_V0: usize = CELL_DATA_LEN - 11;
335
336 pub const MAXLEN_V1: usize = CELL_DATA_LEN - 21;
340
341 pub const MAXLEN: usize = Data::MAXLEN_V0;
347
348 pub fn new(inp: &[u8]) -> crate::Result<Self> {
352 if inp.len() > Data::MAXLEN {
353 return Err(crate::Error::CantEncode("Data message too long"));
354 }
355 if inp.is_empty() {
356 return Err(crate::Error::CantEncode("Empty data message"));
357 }
358 Ok(Self::new_unchecked(inp.into()))
359 }
360
361 pub fn try_split_from(version: RelayCellFormat, inp: &[u8]) -> Option<(Self, &[u8])> {
369 if inp.is_empty() {
370 return None;
371 }
372 let upper_bound = Self::max_body_len(version);
373 let len = std::cmp::min(inp.len(), upper_bound);
374 let (data, remainder) = inp.split_at(len);
375 Some((Self::new_unchecked(data.into()), remainder))
376 }
377
378 fn new_unchecked(body: Vec<u8>) -> Self {
383 debug_assert!((1..=Data::MAXLEN).contains(&body.len()));
384 Data { body }
385 }
386
387 pub fn max_body_len(format: RelayCellFormat) -> usize {
390 match format {
391 RelayCellFormat::V0 => Self::MAXLEN_V0,
392 RelayCellFormat::V1 => Self::MAXLEN_V1,
393 }
394 }
395}
396impl From<Data> for Vec<u8> {
397 fn from(data: Data) -> Vec<u8> {
398 data.body
399 }
400}
401impl AsRef<[u8]> for Data {
402 fn as_ref(&self) -> &[u8] {
403 &self.body[..]
404 }
405}
406
407impl Body for Data {
408 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
409 if r.remaining() == 0 {
410 return Err(Error::InvalidMessage("Empty DATA message".into()));
411 }
412 Ok(Data {
413 body: r.take(r.remaining())?.into(),
414 })
415 }
416 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
417 w.write_all(&self.body);
418 Ok(())
419 }
420}
421
422#[derive(Debug, Clone, Deftly)]
428#[derive_deftly(HasMemoryCost)]
429pub struct End {
430 reason: EndReason,
432 addr: Option<(IpAddr, u32)>,
435}
436
437caret_int! {
438 #[derive(Deftly)]
440 #[derive_deftly(HasMemoryCost)]
441 pub struct EndReason(u8) {
442 MISC = 1,
446 RESOLVEFAILED = 2,
448 CONNECTREFUSED = 3,
450 EXITPOLICY = 4,
452 DESTROY = 5,
454 DONE = 6,
456 TIMEOUT = 7,
458 NOROUTE = 8,
460 HIBERNATING = 9,
462 INTERNAL = 10,
464 RESOURCELIMIT = 11,
466 CONNRESET = 12,
468 TORPROTOCOL = 13,
470 NOTDIRECTORY = 14,
472 }
473}
474
475impl tor_error::HasKind for EndReason {
476 fn kind(&self) -> tor_error::ErrorKind {
477 use tor_error::ErrorKind as EK;
478 use EndReason as E;
479 match *self {
480 E::MISC => EK::RemoteStreamError,
481 E::RESOLVEFAILED => EK::RemoteHostResolutionFailed,
482 E::CONNECTREFUSED => EK::RemoteConnectionRefused,
483 E::EXITPOLICY => EK::ExitPolicyRejected,
484 E::DESTROY => EK::CircuitCollapse,
485 E::DONE => EK::RemoteStreamClosed,
486 E::TIMEOUT => EK::ExitTimeout,
487 E::NOROUTE => EK::RemoteNetworkFailed,
488 E::RESOURCELIMIT | E::HIBERNATING => EK::RelayTooBusy,
489 E::INTERNAL | E::TORPROTOCOL | E::NOTDIRECTORY => EK::TorProtocolViolation,
490 E::CONNRESET => EK::RemoteStreamReset,
491 _ => EK::RemoteStreamError,
492 }
493 }
494}
495
496impl End {
497 pub fn new_misc() -> Self {
501 End {
502 reason: EndReason::MISC,
503 addr: None,
504 }
505 }
506 pub fn new_with_reason(reason: EndReason) -> Self {
508 End { reason, addr: None }
509 }
510 pub fn new_exitpolicy(addr: IpAddr, ttl: u32) -> Self {
513 End {
514 reason: EndReason::EXITPOLICY,
515 addr: Some((addr, ttl)),
516 }
517 }
518 pub fn reason(&self) -> EndReason {
520 self.reason
521 }
522}
523impl Body for End {
524 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
525 if r.remaining() == 0 {
526 return Ok(End {
527 reason: EndReason::MISC,
528 addr: None,
529 });
530 }
531 let reason = r.take_u8()?.into();
532 if reason == EndReason::EXITPOLICY {
533 let addr = match r.remaining() {
534 4 | 8 => IpAddr::V4(r.extract()?),
535 16 | 20 => IpAddr::V6(r.extract()?),
536 _ => {
537 return Ok(End { reason, addr: None });
539 }
540 };
541 let ttl = if r.remaining() == 4 {
542 r.take_u32()?
543 } else {
544 u32::MAX
545 };
546 Ok(End {
547 reason,
548 addr: Some((addr, ttl)),
549 })
550 } else {
551 Ok(End { reason, addr: None })
552 }
553 }
554 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
555 w.write_u8(self.reason.into());
556 if let (EndReason::EXITPOLICY, Some((addr, ttl))) = (self.reason, self.addr) {
557 match addr {
558 IpAddr::V4(v4) => w.write(&v4)?,
559 IpAddr::V6(v6) => w.write(&v6)?,
560 }
561 w.write_u32(ttl);
562 }
563 Ok(())
564 }
565}
566
567impl From<EndReason> for std::io::ErrorKind {
568 fn from(e: EndReason) -> Self {
569 use std::io::ErrorKind::*;
570 match e {
571 EndReason::RESOLVEFAILED => NotFound,
572 EndReason::CONNECTREFUSED => ConnectionRefused,
573 EndReason::EXITPOLICY => ConnectionRefused,
574 EndReason::DESTROY => ConnectionAborted,
575 EndReason::DONE => UnexpectedEof,
576 EndReason::TIMEOUT => TimedOut,
577 EndReason::HIBERNATING => ConnectionRefused,
578 EndReason::RESOURCELIMIT => ConnectionRefused,
579 EndReason::CONNRESET => ConnectionReset,
580 EndReason::TORPROTOCOL => InvalidData,
581 EndReason::NOTDIRECTORY => ConnectionRefused,
582 EndReason::INTERNAL | EndReason::NOROUTE | EndReason::MISC => Other,
583 _ => Other,
584 }
585 }
586}
587
588#[derive(Debug, Clone, Deftly)]
595#[derive_deftly(HasMemoryCost)]
596pub struct Connected {
597 addr: Option<(IpAddr, u32)>,
599}
600impl Connected {
601 pub fn new_empty() -> Self {
603 Connected { addr: None }
604 }
605 pub fn new_with_addr(addr: IpAddr, ttl: u32) -> Self {
607 Connected {
608 addr: Some((addr, ttl)),
609 }
610 }
611}
612impl Body for Connected {
613 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
614 if r.remaining() == 0 {
615 return Ok(Connected { addr: None });
616 }
617 let ipv4 = r.take_u32()?;
618 let addr = if ipv4 == 0 {
619 if r.take_u8()? != 6 {
620 return Err(Error::InvalidMessage(
621 "Invalid address type in CONNECTED cell".into(),
622 ));
623 }
624 IpAddr::V6(r.extract()?)
625 } else {
626 IpAddr::V4(ipv4.into())
627 };
628 let ttl = r.take_u32()?;
629
630 Ok(Connected {
631 addr: Some((addr, ttl)),
632 })
633 }
634 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
635 if let Some((addr, ttl)) = self.addr {
636 match addr {
637 IpAddr::V4(v4) => w.write(&v4)?,
638 IpAddr::V6(v6) => {
639 w.write_u32(0);
640 w.write_u8(6);
641 w.write(&v6)?;
642 }
643 }
644 w.write_u32(ttl);
645 }
646 Ok(())
647 }
648}
649
650#[derive(Debug, Clone, Copy, Eq, PartialEq, Deftly)]
655#[derive_deftly(HasMemoryCost)]
656pub struct SendmeTag {
657 len: NonZeroU8,
662 tag: CtByteArray<20>,
668}
669impl From<[u8; 20]> for SendmeTag {
670 #[inline]
672 fn from(value: [u8; 20]) -> Self {
673 Self {
674 len: NonZeroU8::new(20).expect("20 was not nonzero?"),
675 tag: CtByteArray::from(value),
676 }
677 }
678}
679impl From<[u8; 16]> for SendmeTag {
680 #[inline]
682 fn from(value: [u8; 16]) -> Self {
683 let mut tag = CtByteArray::from([0; 20]);
684 tag.as_mut()[0..16].copy_from_slice(&value[..]);
685 Self {
686 len: NonZeroU8::new(16).expect("16 was not nonzero?"),
687 tag,
688 }
689 }
690}
691impl AsRef<[u8]> for SendmeTag {
692 fn as_ref(&self) -> &[u8] {
693 &self.tag.as_ref()[0..usize::from(u8::from(self.len))]
694 }
695}
696#[derive(Clone, Debug, thiserror::Error)]
698#[non_exhaustive]
699#[error("Invalid size {} on SENDME tag", len)]
700pub struct InvalidSendmeTag {
701 len: usize,
703}
704impl From<InvalidSendmeTag> for tor_bytes::Error {
705 fn from(_: InvalidSendmeTag) -> Self {
706 tor_bytes::Error::BadLengthValue
707 }
708}
709
710impl<'a> TryFrom<&'a [u8]> for SendmeTag {
711 type Error = InvalidSendmeTag;
712
713 #[inline]
715 fn try_from(value: &'a [u8]) -> std::result::Result<Self, Self::Error> {
716 match value.len() {
717 16 => {
718 let a: [u8; 16] = value.try_into().expect("16 was not 16?");
719 Ok(Self::from(a))
720 }
721 20 => {
722 let a: [u8; 20] = value.try_into().expect("20 was not 20?");
723 Ok(Self::from(a))
724 }
725 _ => Err(InvalidSendmeTag { len: value.len() }),
726 }
727 }
728}
729
730#[derive(Debug, Clone, Deftly)]
747#[derive_deftly(HasMemoryCost)]
748pub struct Sendme {
749 tag: Option<SendmeTag>,
751}
752impl Sendme {
753 pub fn new_empty() -> Self {
758 Sendme { tag: None }
759 }
760 pub fn new_tag(x: [u8; 20]) -> Self {
762 Sendme {
763 tag: Some(x.into()),
764 }
765 }
766 pub fn into_sendme_tag(self) -> Option<SendmeTag> {
768 self.tag
769 }
770}
771impl From<SendmeTag> for Sendme {
772 fn from(value: SendmeTag) -> Self {
773 Self { tag: Some(value) }
774 }
775}
776impl Body for Sendme {
777 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
778 let tag = if r.remaining() == 0 {
779 None
780 } else {
781 let ver = r.take_u8()?;
782 match ver {
783 0 => None,
784 1 => {
785 let dlen = r.take_u16()?;
786 Some(r.take(dlen as usize)?.try_into()?)
787 }
788 _ => {
789 return Err(Error::InvalidMessage("Unrecognized SENDME version.".into()));
790 }
791 }
792 };
793 Ok(Sendme { tag })
794 }
795 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
796 match self.tag {
797 None => (),
798 Some(x) => {
799 w.write_u8(1);
800 let x = x.as_ref();
801 let bodylen: u16 = x
802 .len()
803 .try_into()
804 .map_err(|_| EncodeError::BadLengthValue)?;
805 w.write_u16(bodylen);
806 w.write_all(x);
807 }
808 }
809 Ok(())
810 }
811}
812
813#[derive(Debug, Clone, Deftly)]
818#[derive_deftly(HasMemoryCost)]
819pub struct Extend {
820 addr: Ipv4Addr,
822 port: u16,
824 handshake: Vec<u8>,
826 rsaid: RsaIdentity,
828}
829impl Extend {
830 pub fn new(addr: Ipv4Addr, port: u16, handshake: Vec<u8>, rsaid: RsaIdentity) -> Self {
832 Extend {
833 addr,
834 port,
835 handshake,
836 rsaid,
837 }
838 }
839}
840impl Body for Extend {
841 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
842 let addr = r.extract()?;
843 let port = r.take_u16()?;
844 let handshake = r.take(TAP_C_HANDSHAKE_LEN)?.into();
845 let rsaid = r.extract()?;
846 Ok(Extend {
847 addr,
848 port,
849 handshake,
850 rsaid,
851 })
852 }
853 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
854 w.write(&self.addr)?;
855 w.write_u16(self.port);
856 w.write_all(&self.handshake[..]);
857 w.write(&self.rsaid)?;
858 Ok(())
859 }
860}
861
862#[derive(Debug, Clone, Deftly)]
868#[derive_deftly(HasMemoryCost)]
869pub struct Extended {
870 handshake: Vec<u8>,
872}
873impl Extended {
874 pub fn new(handshake: Vec<u8>) -> Self {
876 Extended { handshake }
877 }
878}
879impl Body for Extended {
880 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
881 let handshake = r.take(TAP_S_HANDSHAKE_LEN)?.into();
882 Ok(Extended { handshake })
883 }
884 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
885 w.write_all(&self.handshake);
886 Ok(())
887 }
888}
889
890#[derive(Debug, Clone, Deftly)]
905#[derive_deftly(HasMemoryCost)]
906pub struct Extend2 {
907 linkspec: Vec<EncodedLinkSpec>,
913 handshake_type: HandshakeType,
915 handshake: Vec<u8>,
917}
918impl Extend2 {
919 pub fn new(
921 linkspec: Vec<EncodedLinkSpec>,
922 handshake_type: HandshakeType,
923 handshake: Vec<u8>,
924 ) -> Self {
925 Extend2 {
926 linkspec,
927 handshake_type,
928 handshake,
929 }
930 }
931
932 pub fn handshake_type(&self) -> HandshakeType {
934 self.handshake_type
935 }
936
937 pub fn handshake(&self) -> &[u8] {
939 &self.handshake[..]
940 }
941}
942
943impl Body for Extend2 {
944 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
945 let n = r.take_u8()?;
946 let linkspec = r.extract_n(n as usize)?;
947 let handshake_type = r.take_u16()?.into();
948 let hlen = r.take_u16()?;
949 let handshake = r.take(hlen as usize)?.into();
950 Ok(Extend2 {
951 linkspec,
952 handshake_type,
953 handshake,
954 })
955 }
956 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
957 let n_linkspecs: u8 = self
958 .linkspec
959 .len()
960 .try_into()
961 .map_err(|_| EncodeError::BadLengthValue)?;
962 w.write_u8(n_linkspecs);
963 for ls in &self.linkspec {
964 w.write(ls)?;
965 }
966 w.write_u16(self.handshake_type.into());
967 let handshake_len: u16 = self
968 .handshake
969 .len()
970 .try_into()
971 .map_err(|_| EncodeError::BadLengthValue)?;
972 w.write_u16(handshake_len);
973 w.write_all(&self.handshake[..]);
974 Ok(())
975 }
976}
977
978#[derive(Debug, Clone, Deftly)]
984#[derive_deftly(HasMemoryCost)]
985pub struct Extended2 {
986 handshake: Vec<u8>,
989}
990impl Extended2 {
991 pub fn new(handshake: Vec<u8>) -> Self {
993 Extended2 { handshake }
994 }
995 pub fn into_body(self) -> Vec<u8> {
997 self.handshake
998 }
999}
1000impl Body for Extended2 {
1001 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1002 let hlen = r.take_u16()?;
1003 let handshake = r.take(hlen as usize)?;
1004 Ok(Extended2 {
1005 handshake: handshake.into(),
1006 })
1007 }
1008 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1009 let handshake_len: u16 = self
1010 .handshake
1011 .len()
1012 .try_into()
1013 .map_err(|_| EncodeError::BadLengthValue)?;
1014 w.write_u16(handshake_len);
1015 w.write_all(&self.handshake[..]);
1016 Ok(())
1017 }
1018}
1019
1020#[derive(Debug, Clone, Deftly)]
1028#[derive_deftly(HasMemoryCost)]
1029pub struct Truncated {
1030 reason: DestroyReason,
1032}
1033impl Truncated {
1034 pub fn new(reason: DestroyReason) -> Self {
1036 Truncated { reason }
1037 }
1038 pub fn reason(self) -> DestroyReason {
1040 self.reason
1041 }
1042}
1043impl Body for Truncated {
1044 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1045 Ok(Truncated {
1046 reason: r.take_u8()?.into(),
1047 })
1048 }
1049 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1050 w.write_u8(self.reason.into());
1051 Ok(())
1052 }
1053}
1054
1055#[derive(Debug, Clone, Deftly)]
1062#[derive_deftly(HasMemoryCost)]
1063pub struct Resolve {
1064 query: Vec<u8>,
1066}
1067impl Resolve {
1068 pub fn new(s: &str) -> Self {
1070 Resolve {
1071 query: s.as_bytes().into(),
1072 }
1073 }
1074 pub fn new_reverse(addr: &IpAddr) -> Self {
1076 let query = match addr {
1077 IpAddr::V4(v4) => {
1078 let [a, b, c, d] = v4.octets();
1079 format!("{}.{}.{}.{}.in-addr.arpa", d, c, b, a)
1080 }
1081 IpAddr::V6(v6) => {
1082 let mut s = String::with_capacity(72);
1083 for o in v6.octets().iter().rev() {
1084 let high_nybble = o >> 4;
1085 let low_nybble = o & 15;
1086 write!(s, "{:x}.{:x}.", low_nybble, high_nybble)
1087 .expect("write to string failed");
1088 }
1089 write!(s, "ip6.arpa").expect("write to string failed");
1090 s
1091 }
1092 };
1093 Resolve {
1094 query: query.into_bytes(),
1095 }
1096 }
1097}
1098impl Body for Resolve {
1099 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1100 let query = r.take_until(0)?;
1101 Ok(Resolve {
1102 query: query.into(),
1103 })
1104 }
1105 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1106 w.write_all(&self.query[..]);
1107 w.write_u8(0);
1108 Ok(())
1109 }
1110}
1111
1112#[derive(Debug, Clone, Eq, PartialEq, Deftly)]
1114#[derive_deftly(HasMemoryCost)]
1115#[non_exhaustive]
1116pub enum ResolvedVal {
1117 Ip(IpAddr),
1119 Hostname(Vec<u8>),
1121 TransientError,
1123 NontransientError,
1125 Unrecognized(u8, Vec<u8>),
1127}
1128
1129const RES_HOSTNAME: u8 = 0;
1131const RES_IPV4: u8 = 4;
1133const RES_IPV6: u8 = 6;
1135const RES_ERR_TRANSIENT: u8 = 0xF0;
1137const RES_ERR_NONTRANSIENT: u8 = 0xF1;
1139
1140impl Readable for ResolvedVal {
1141 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1142 fn res_len(tp: u8) -> Option<usize> {
1145 match tp {
1146 RES_IPV4 => Some(4),
1147 RES_IPV6 => Some(16),
1148 _ => None,
1149 }
1150 }
1151 let tp = r.take_u8()?;
1152 let len = r.take_u8()? as usize;
1153 if let Some(expected_len) = res_len(tp) {
1154 if len != expected_len {
1155 return Err(Error::InvalidMessage(
1156 "Wrong length for RESOLVED answer".into(),
1157 ));
1158 }
1159 }
1160 Ok(match tp {
1161 RES_HOSTNAME => Self::Hostname(r.take(len)?.into()),
1162 RES_IPV4 => Self::Ip(IpAddr::V4(r.extract()?)),
1163 RES_IPV6 => Self::Ip(IpAddr::V6(r.extract()?)),
1164 RES_ERR_TRANSIENT => {
1165 r.advance(len)?;
1166 Self::TransientError
1167 }
1168 RES_ERR_NONTRANSIENT => {
1169 r.advance(len)?;
1170 Self::NontransientError
1171 }
1172 _ => Self::Unrecognized(tp, r.take(len)?.into()),
1173 })
1174 }
1175}
1176
1177impl Writeable for ResolvedVal {
1178 fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
1179 match self {
1180 Self::Hostname(h) => {
1181 w.write_u8(RES_HOSTNAME);
1182 let h_len: u8 = h
1183 .len()
1184 .try_into()
1185 .map_err(|_| EncodeError::BadLengthValue)?;
1186 w.write_u8(h_len);
1187 w.write_all(&h[..]);
1188 }
1189 Self::Ip(IpAddr::V4(a)) => {
1190 w.write_u8(RES_IPV4);
1191 w.write_u8(4); w.write(a)?;
1193 }
1194 Self::Ip(IpAddr::V6(a)) => {
1195 w.write_u8(RES_IPV6);
1196 w.write_u8(16); w.write(a)?;
1198 }
1199 Self::TransientError => {
1200 w.write_u8(RES_ERR_TRANSIENT);
1201 w.write_u8(0); }
1203 Self::NontransientError => {
1204 w.write_u8(RES_ERR_NONTRANSIENT);
1205 w.write_u8(0); }
1207 Self::Unrecognized(tp, v) => {
1208 w.write_u8(*tp);
1209 let v_len: u8 = v
1210 .len()
1211 .try_into()
1212 .map_err(|_| EncodeError::BadLengthValue)?;
1213 w.write_u8(v_len);
1214 w.write_all(&v[..]);
1215 }
1216 }
1217 Ok(())
1218 }
1219}
1220
1221#[derive(Debug, Clone, Deftly)]
1226#[derive_deftly(HasMemoryCost)]
1227pub struct Resolved {
1228 answers: Vec<(ResolvedVal, u32)>,
1230}
1231impl Resolved {
1232 pub fn new_empty() -> Self {
1234 Resolved {
1235 answers: Vec::new(),
1236 }
1237 }
1238 pub fn new_err(transient: bool, ttl: u32) -> Self {
1243 let mut res = Self::new_empty();
1244 let err = if transient {
1245 ResolvedVal::TransientError
1246 } else {
1247 ResolvedVal::NontransientError
1248 };
1249 res.add_answer(err, ttl);
1250 res
1251 }
1252 pub fn add_answer(&mut self, answer: ResolvedVal, ttl: u32) {
1254 self.answers.push((answer, ttl));
1255 }
1256
1257 pub fn into_answers(self) -> Vec<(ResolvedVal, u32)> {
1265 self.answers
1266 }
1267}
1268impl Body for Resolved {
1269 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1270 let mut answers = Vec::new();
1271 while r.remaining() > 0 {
1272 let rv = r.extract()?;
1273 let ttl = r.take_u32()?;
1274 answers.push((rv, ttl));
1275 }
1276 Ok(Resolved { answers })
1277 }
1278 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1279 for (rv, ttl) in &self.answers {
1280 w.write(rv)?;
1281 w.write_u32(*ttl);
1282 }
1283 Ok(())
1284 }
1285}
1286
1287#[derive(Debug, Clone, Deftly)]
1291#[derive_deftly(HasMemoryCost)]
1292pub struct Unrecognized {
1293 cmd: RelayCmd,
1295 body: Vec<u8>,
1297}
1298
1299impl Unrecognized {
1300 pub fn new<B>(cmd: RelayCmd, body: B) -> Self
1302 where
1303 B: Into<Vec<u8>>,
1304 {
1305 let body = body.into();
1306 Unrecognized { cmd, body }
1307 }
1308
1309 pub fn cmd(&self) -> RelayCmd {
1311 self.cmd
1312 }
1313 pub fn decode_with_cmd(cmd: RelayCmd, r: &mut Reader<'_>) -> Result<Self> {
1315 let mut r = Unrecognized::decode_from_reader(r)?;
1316 r.cmd = cmd;
1317 Ok(r)
1318 }
1319}
1320
1321impl Body for Unrecognized {
1322 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1323 Ok(Unrecognized {
1324 cmd: 0.into(),
1325 body: r.take(r.remaining())?.into(),
1326 })
1327 }
1328 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1329 w.write_all(&self.body[..]);
1330 Ok(())
1331 }
1332}
1333
1334macro_rules! empty_body {
1336 {
1337 $(#[$meta:meta])*
1338 pub struct $name:ident {}
1339 } => {
1340 $(#[$meta])*
1341 #[derive(Clone,Debug,Default,derive_deftly::Deftly)]
1342 #[derive_deftly(tor_memquota::HasMemoryCost)]
1343 #[non_exhaustive]
1344 pub struct $name {}
1345 impl $crate::relaycell::msg::Body for $name {
1346 fn decode_from_reader(_r: &mut Reader<'_>) -> Result<Self> {
1347 Ok(Self::default())
1348 }
1349 fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
1350 Ok(())
1351 }
1352 }
1353 }
1354}
1355pub(crate) use empty_body;
1356
1357empty_body! {
1358 pub struct Drop {}
1360}
1361empty_body! {
1362 pub struct Truncate {}
1364}
1365empty_body! {
1366 pub struct BeginDir {}
1368}
1369
1370macro_rules! msg_impl_relaymsg {
1380 ($($body:ident),* $(,)?) =>
1381 {paste::paste!{
1382 $(impl crate::relaycell::RelayMsg for $body {
1383 fn cmd(&self) -> crate::relaycell::RelayCmd { crate::relaycell::RelayCmd::[< $body:snake:upper >] }
1384 fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1385 crate::relaycell::msg::Body::encode_onto(self, w)
1386 }
1387 fn decode_from_reader(cmd: RelayCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1388 if cmd != crate::relaycell::RelayCmd::[< $body:snake:upper >] {
1389 return Err(tor_bytes::Error::InvalidMessage(
1390 format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1391 ));
1392 }
1393 crate::relaycell::msg::Body::decode_from_reader(r)
1394 }
1395 }
1396
1397 impl TryFrom<AnyRelayMsg> for $body {
1398 type Error = crate::Error;
1399 fn try_from(msg: AnyRelayMsg) -> crate::Result<$body> {
1400 use crate::relaycell::RelayMsg;
1401 match msg {
1402 AnyRelayMsg::$body(b) => Ok(b),
1403 _ => Err(crate::Error::CircProto(format!("Expected {}; got {}" ,
1404 stringify!([<$body:snake:upper>]),
1405 msg.cmd())) ),
1406 }
1407 }
1408 }
1409 )*
1410 }}
1411}
1412
1413msg_impl_relaymsg!(
1414 Begin, Data, End, Connected, Sendme, Extend, Extended, Extend2, Extended2, Truncate, Truncated,
1415 Drop, Resolve, Resolved, BeginDir,
1416);
1417
1418#[cfg(feature = "experimental-udp")]
1419msg_impl_relaymsg!(ConnectUdp, ConnectedUdp, Datagram);
1420
1421#[cfg(feature = "hs")]
1422msg_impl_relaymsg!(
1423 EstablishIntro,
1424 EstablishRendezvous,
1425 Introduce1,
1426 Introduce2,
1427 Rendezvous1,
1428 Rendezvous2,
1429 IntroEstablished,
1430 RendezvousEstablished,
1431 IntroduceAck,
1432);
1433
1434#[cfg(feature = "conflux")]
1435msg_impl_relaymsg!(ConfluxSwitch, ConfluxLink, ConfluxLinked, ConfluxLinkedAck);
1436
1437#[cfg(feature = "flowctl-cc")]
1438msg_impl_relaymsg!(Xon, Xoff);
1439
1440#[cfg(test)]
1441mod test {
1442 #![allow(clippy::bool_assert_comparison)]
1444 #![allow(clippy::clone_on_copy)]
1445 #![allow(clippy::dbg_macro)]
1446 #![allow(clippy::mixed_attributes_style)]
1447 #![allow(clippy::print_stderr)]
1448 #![allow(clippy::print_stdout)]
1449 #![allow(clippy::single_char_pattern)]
1450 #![allow(clippy::unwrap_used)]
1451 #![allow(clippy::unchecked_duration_subtraction)]
1452 #![allow(clippy::useless_vec)]
1453 #![allow(clippy::needless_pass_by_value)]
1454 use super::*;
1457
1458 #[test]
1459 fn sendme_tags() {
1460 let ts: Vec<SendmeTag> = vec![
1462 (*b"Yea, on the word of ").into(),
1463 (*b"a Bloom, ye shal").into(),
1464 (*b"l ere long enter int").into(),
1465 (*b"o the golden cit").into(),
1466 ];
1467
1468 for (i1, i2) in (0..4).zip(0..4) {
1469 if i1 == i2 {
1470 assert_eq!(ts[i1], ts[i2]);
1471 } else {
1472 assert_ne!(ts[i1], ts[i2]);
1473 }
1474 }
1475
1476 assert_eq!(ts[0].as_ref(), &b"Yea, on the word of "[..]);
1477 assert_eq!(ts[3].as_ref(), &b"o the golden cit"[..]);
1478
1479 assert_eq!(ts[1], b"a Bloom, ye shal"[..].try_into().unwrap());
1480 assert_eq!(ts[2], b"l ere long enter int"[..].try_into().unwrap());
1481
1482 assert!(matches!(
1484 SendmeTag::try_from(&b"o the golden ci"[..]),
1485 Err(InvalidSendmeTag { .. }),
1486 ));
1487 }
1488}