1use super::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 tor_bytes::{EncodeError, EncodeResult, Error, Result};
16use tor_bytes::{Readable, Reader, Writeable, Writer};
17use tor_linkspec::EncodedLinkSpec;
18use tor_llcrypto::pk::rsa::RsaIdentity;
19use tor_memquota::{derive_deftly_template_HasMemoryCost, memory_cost_structural_copy};
20
21use bitflags::bitflags;
22
23#[cfg(feature = "conflux")]
24#[cfg_attr(docsrs, doc(cfg(feature = "conflux")))]
25pub use super::conflux::{ConfluxLink, ConfluxLinked, ConfluxLinkedAck, ConfluxSwitch};
26
27#[cfg(feature = "hs")]
28#[cfg_attr(docsrs, doc(cfg(feature = "hs")))]
29pub use super::hs::{
30 est_intro::EstablishIntro, EstablishRendezvous, IntroEstablished, Introduce1, Introduce2,
31 IntroduceAck, Rendezvous1, Rendezvous2, RendezvousEstablished,
32};
33#[cfg(feature = "experimental-udp")]
34#[cfg_attr(docsrs, doc(cfg(feature = "experimental-udp")))]
35pub use super::udp::{ConnectUdp, ConnectedUdp, Datagram};
36
37crate::restrict::restricted_msg! {
38#[derive(Debug, Clone, Deftly)]
40#[derive_deftly(HasMemoryCost)]
41#[non_exhaustive]
42@omit_from "avoid_conflict_with_a_blanket_implementation"
43pub enum AnyRelayMsg : RelayMsg {
44 Begin,
46 Data,
48 End,
50 Connected,
52 Sendme,
54 Extend,
56 Extended,
58 Extend2,
60 Extended2,
62 Truncate,
64 Truncated,
66 Drop,
68 Resolve,
70 Resolved,
72 BeginDir,
74 [feature = "experimental-udp"]
76 ConnectUdp,
77 [feature = "experimental-udp"]
79 ConnectedUdp,
80 [feature = "experimental-udp"]
82 Datagram,
83 [feature = "conflux"]
85 ConfluxLink,
86 [feature = "conflux"]
88 ConfluxLinked,
89 [feature = "conflux"]
91 ConfluxLinkedAck,
92 [feature = "conflux"]
94 ConfluxSwitch,
95 [feature = "hs"]
97 EstablishIntro,
98 [feature = "hs"]
100 EstablishRendezvous,
101 [feature = "hs"]
103 Introduce1,
104 [feature = "hs"]
106 Introduce2,
107 [feature = "hs"]
109 Rendezvous1,
110 [feature = "hs"]
112 Rendezvous2,
113 [feature = "hs"]
115 IntroEstablished,
116 [feature = "hs"]
118 RendezvousEstablished,
119 [feature = "hs"]
121 IntroduceAck,
122
123 _ =>
124 Unrecognized,
126 }
127}
128
129pub trait Body: Sized {
131 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self>;
133 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()>;
135}
136
137bitflags! {
138 #[derive(Clone, Copy, Debug)]
143 pub struct BeginFlags : u32 {
144 const IPV6_OKAY = (1<<0);
146 const IPV4_NOT_OKAY = (1<<1);
148 const IPV6_PREFERRED = (1<<2);
150 }
151}
152memory_cost_structural_copy!(BeginFlags);
153impl From<u32> for BeginFlags {
154 fn from(v: u32) -> Self {
155 BeginFlags::from_bits_truncate(v)
156 }
157}
158
159#[derive(Clone, Default, Copy, Debug, Eq, PartialEq)]
162#[non_exhaustive]
163pub enum IpVersionPreference {
164 Ipv4Only,
166 #[default]
168 Ipv4Preferred,
169 Ipv6Preferred,
171 Ipv6Only,
173}
174impl From<IpVersionPreference> for BeginFlags {
175 fn from(v: IpVersionPreference) -> Self {
176 use IpVersionPreference::*;
177 match v {
178 Ipv4Only => 0.into(),
179 Ipv4Preferred => BeginFlags::IPV6_OKAY,
180 Ipv6Preferred => BeginFlags::IPV6_OKAY | BeginFlags::IPV6_PREFERRED,
181 Ipv6Only => BeginFlags::IPV4_NOT_OKAY,
182 }
183 }
184}
185
186#[derive(Debug, Clone, Deftly)]
197#[derive_deftly(HasMemoryCost)]
198pub struct Begin {
199 addr: Vec<u8>,
201 port: u16,
203 flags: BeginFlags,
205}
206
207impl Begin {
208 pub fn new<F>(addr: &str, port: u16, flags: F) -> crate::Result<Self>
210 where
211 F: Into<BeginFlags>,
212 {
213 if !addr.is_ascii() {
214 return Err(crate::Error::BadStreamAddress);
215 }
216 let mut addr = addr.to_string();
217 addr.make_ascii_lowercase();
218 Ok(Begin {
219 addr: addr.into_bytes(),
220 port,
221 flags: flags.into(),
222 })
223 }
224
225 pub fn addr(&self) -> &[u8] {
227 &self.addr[..]
228 }
229
230 pub fn port(&self) -> u16 {
232 self.port
233 }
234
235 pub fn flags(&self) -> BeginFlags {
237 self.flags
238 }
239}
240
241impl Body for Begin {
242 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
243 let addr = {
244 if r.peek(1)? == b"[" {
245 r.advance(1)?;
247 let a = r.take_until(b']')?;
248 let colon = r.take_u8()?;
249 if colon != b':' {
250 return Err(Error::InvalidMessage("missing port in begin cell".into()));
251 }
252 a
253 } else {
254 r.take_until(b':')?
256 }
257 };
258 let port = r.take_until(0)?;
259 let flags = if r.remaining() >= 4 { r.take_u32()? } else { 0 };
260
261 if !addr.is_ascii() {
262 return Err(Error::InvalidMessage(
263 "target address in begin cell not ascii".into(),
264 ));
265 }
266
267 let port = std::str::from_utf8(port)
268 .map_err(|_| Error::InvalidMessage("port in begin cell not utf8".into()))?;
269
270 let port = port
271 .parse()
272 .map_err(|_| Error::InvalidMessage("port in begin cell not a valid port".into()))?;
273
274 Ok(Begin {
275 addr: addr.into(),
276 port,
277 flags: flags.into(),
278 })
279 }
280 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
281 if self.addr.contains(&b':') {
282 w.write_u8(b'[');
283 w.write_all(&self.addr[..]);
284 w.write_u8(b']');
285 } else {
286 w.write_all(&self.addr[..]);
287 }
288 w.write_u8(b':');
289 w.write_all(self.port.to_string().as_bytes());
290 w.write_u8(0);
291 if self.flags.bits() != 0 {
292 w.write_u32(self.flags.bits());
293 }
294 Ok(())
295 }
296}
297
298#[derive(Debug, Clone, Deftly)]
306#[derive_deftly(HasMemoryCost)]
307pub struct Data {
308 body: Vec<u8>,
317}
318impl Data {
319 pub const MAXLEN: usize = CELL_DATA_LEN - 11;
322
323 pub fn new(inp: &[u8]) -> crate::Result<Self> {
327 if inp.len() > Data::MAXLEN {
328 return Err(crate::Error::CantEncode("Data message too long"));
329 }
330 if inp.is_empty() {
331 return Err(crate::Error::CantEncode("Empty data message"));
332 }
333 Ok(Self::new_unchecked(inp.into()))
334 }
335
336 #[deprecated(since = "0.16.1", note = "Use try_split_from instead.")]
346 pub fn split_from(inp: &[u8]) -> (Self, &[u8]) {
347 Self::try_split_from(inp).expect("Tried to split a Data message from an empty input.")
348 }
349
350 pub fn try_split_from(inp: &[u8]) -> Option<(Self, &[u8])> {
358 if inp.is_empty() {
359 return None;
360 }
361 let len = std::cmp::min(inp.len(), Data::MAXLEN);
362 let (data, remainder) = inp.split_at(len);
363 Some((Self::new_unchecked(data.into()), remainder))
364 }
365
366 fn new_unchecked(body: Vec<u8>) -> Self {
371 debug_assert!((1..=Data::MAXLEN).contains(&body.len()));
372 Data { body }
373 }
374}
375impl From<Data> for Vec<u8> {
376 fn from(data: Data) -> Vec<u8> {
377 data.body
378 }
379}
380impl AsRef<[u8]> for Data {
381 fn as_ref(&self) -> &[u8] {
382 &self.body[..]
383 }
384}
385
386impl Body for Data {
387 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
388 if r.remaining() == 0 {
389 return Err(Error::InvalidMessage("Empty DATA message".into()));
390 }
391 Ok(Data {
392 body: r.take(r.remaining())?.into(),
393 })
394 }
395 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
396 w.write_all(&self.body);
397 Ok(())
398 }
399}
400
401#[derive(Debug, Clone, Deftly)]
407#[derive_deftly(HasMemoryCost)]
408pub struct End {
409 reason: EndReason,
411 addr: Option<(IpAddr, u32)>,
414}
415
416caret_int! {
417 #[derive(Deftly)]
419 #[derive_deftly(HasMemoryCost)]
420 pub struct EndReason(u8) {
421 MISC = 1,
425 RESOLVEFAILED = 2,
427 CONNECTREFUSED = 3,
429 EXITPOLICY = 4,
431 DESTROY = 5,
433 DONE = 6,
435 TIMEOUT = 7,
437 NOROUTE = 8,
439 HIBERNATING = 9,
441 INTERNAL = 10,
443 RESOURCELIMIT = 11,
445 CONNRESET = 12,
447 TORPROTOCOL = 13,
449 NOTDIRECTORY = 14,
451 }
452}
453
454impl tor_error::HasKind for EndReason {
455 fn kind(&self) -> tor_error::ErrorKind {
456 use tor_error::ErrorKind as EK;
457 use EndReason as E;
458 match *self {
459 E::MISC => EK::RemoteStreamError,
460 E::RESOLVEFAILED => EK::RemoteHostResolutionFailed,
461 E::CONNECTREFUSED => EK::RemoteConnectionRefused,
462 E::EXITPOLICY => EK::ExitPolicyRejected,
463 E::DESTROY => EK::CircuitCollapse,
464 E::DONE => EK::RemoteStreamClosed,
465 E::TIMEOUT => EK::ExitTimeout,
466 E::NOROUTE => EK::RemoteNetworkFailed,
467 E::RESOURCELIMIT | E::HIBERNATING => EK::RelayTooBusy,
468 E::INTERNAL | E::TORPROTOCOL | E::NOTDIRECTORY => EK::TorProtocolViolation,
469 E::CONNRESET => EK::RemoteStreamReset,
470 _ => EK::RemoteStreamError,
471 }
472 }
473}
474
475impl End {
476 pub fn new_misc() -> Self {
480 End {
481 reason: EndReason::MISC,
482 addr: None,
483 }
484 }
485 pub fn new_with_reason(reason: EndReason) -> Self {
487 End { reason, addr: None }
488 }
489 pub fn new_exitpolicy(addr: IpAddr, ttl: u32) -> Self {
492 End {
493 reason: EndReason::EXITPOLICY,
494 addr: Some((addr, ttl)),
495 }
496 }
497 pub fn reason(&self) -> EndReason {
499 self.reason
500 }
501}
502impl Body for End {
503 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
504 if r.remaining() == 0 {
505 return Ok(End {
506 reason: EndReason::MISC,
507 addr: None,
508 });
509 }
510 let reason = r.take_u8()?.into();
511 if reason == EndReason::EXITPOLICY {
512 let addr = match r.remaining() {
513 4 | 8 => IpAddr::V4(r.extract()?),
514 16 | 20 => IpAddr::V6(r.extract()?),
515 _ => {
516 return Ok(End { reason, addr: None });
518 }
519 };
520 let ttl = if r.remaining() == 4 {
521 r.take_u32()?
522 } else {
523 u32::MAX
524 };
525 Ok(End {
526 reason,
527 addr: Some((addr, ttl)),
528 })
529 } else {
530 Ok(End { reason, addr: None })
531 }
532 }
533 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
534 w.write_u8(self.reason.into());
535 if let (EndReason::EXITPOLICY, Some((addr, ttl))) = (self.reason, self.addr) {
536 match addr {
537 IpAddr::V4(v4) => w.write(&v4)?,
538 IpAddr::V6(v6) => w.write(&v6)?,
539 }
540 w.write_u32(ttl);
541 }
542 Ok(())
543 }
544}
545
546impl From<EndReason> for std::io::ErrorKind {
547 fn from(e: EndReason) -> Self {
548 use std::io::ErrorKind::*;
549 match e {
550 EndReason::RESOLVEFAILED => NotFound,
551 EndReason::CONNECTREFUSED => ConnectionRefused,
552 EndReason::EXITPOLICY => ConnectionRefused,
553 EndReason::DESTROY => ConnectionAborted,
554 EndReason::DONE => UnexpectedEof,
555 EndReason::TIMEOUT => TimedOut,
556 EndReason::HIBERNATING => ConnectionRefused,
557 EndReason::RESOURCELIMIT => ConnectionRefused,
558 EndReason::CONNRESET => ConnectionReset,
559 EndReason::TORPROTOCOL => InvalidData,
560 EndReason::NOTDIRECTORY => ConnectionRefused,
561 EndReason::INTERNAL | EndReason::NOROUTE | EndReason::MISC => Other,
562 _ => Other,
563 }
564 }
565}
566
567#[derive(Debug, Clone, Deftly)]
574#[derive_deftly(HasMemoryCost)]
575pub struct Connected {
576 addr: Option<(IpAddr, u32)>,
578}
579impl Connected {
580 pub fn new_empty() -> Self {
582 Connected { addr: None }
583 }
584 pub fn new_with_addr(addr: IpAddr, ttl: u32) -> Self {
586 Connected {
587 addr: Some((addr, ttl)),
588 }
589 }
590}
591impl Body for Connected {
592 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
593 if r.remaining() == 0 {
594 return Ok(Connected { addr: None });
595 }
596 let ipv4 = r.take_u32()?;
597 let addr = if ipv4 == 0 {
598 if r.take_u8()? != 6 {
599 return Err(Error::InvalidMessage(
600 "Invalid address type in CONNECTED cell".into(),
601 ));
602 }
603 IpAddr::V6(r.extract()?)
604 } else {
605 IpAddr::V4(ipv4.into())
606 };
607 let ttl = r.take_u32()?;
608
609 Ok(Connected {
610 addr: Some((addr, ttl)),
611 })
612 }
613 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
614 if let Some((addr, ttl)) = self.addr {
615 match addr {
616 IpAddr::V4(v4) => w.write(&v4)?,
617 IpAddr::V6(v6) => {
618 w.write_u32(0);
619 w.write_u8(6);
620 w.write(&v6)?;
621 }
622 }
623 w.write_u32(ttl);
624 }
625 Ok(())
626 }
627}
628
629#[derive(Debug, Clone, Deftly)]
646#[derive_deftly(HasMemoryCost)]
647pub struct Sendme {
648 digest: Option<Vec<u8>>,
650}
651impl Sendme {
652 pub fn new_empty() -> Self {
657 Sendme { digest: None }
658 }
659 pub fn new_tag(x: [u8; 20]) -> Self {
661 Sendme {
662 digest: Some(x.into()),
663 }
664 }
665 pub fn into_tag(self) -> Option<Vec<u8>> {
667 self.digest
668 }
669}
670impl Body for Sendme {
671 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
672 let digest = if r.remaining() == 0 {
673 None
674 } else {
675 let ver = r.take_u8()?;
676 match ver {
677 0 => None,
678 1 => {
679 let dlen = r.take_u16()?;
680 Some(r.take(dlen as usize)?.into())
681 }
682 _ => {
683 return Err(Error::InvalidMessage("Unrecognized SENDME version.".into()));
684 }
685 }
686 };
687 Ok(Sendme { digest })
688 }
689 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
690 match self.digest {
691 None => (),
692 Some(x) => {
693 w.write_u8(1);
694 let bodylen: u16 = x
695 .len()
696 .try_into()
697 .map_err(|_| EncodeError::BadLengthValue)?;
698 w.write_u16(bodylen);
699 w.write_all(&x);
700 }
701 }
702 Ok(())
703 }
704}
705
706#[derive(Debug, Clone, Deftly)]
711#[derive_deftly(HasMemoryCost)]
712pub struct Extend {
713 addr: Ipv4Addr,
715 port: u16,
717 handshake: Vec<u8>,
719 rsaid: RsaIdentity,
721}
722impl Extend {
723 pub fn new(addr: Ipv4Addr, port: u16, handshake: Vec<u8>, rsaid: RsaIdentity) -> Self {
725 Extend {
726 addr,
727 port,
728 handshake,
729 rsaid,
730 }
731 }
732}
733impl Body for Extend {
734 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
735 let addr = r.extract()?;
736 let port = r.take_u16()?;
737 let handshake = r.take(TAP_C_HANDSHAKE_LEN)?.into();
738 let rsaid = r.extract()?;
739 Ok(Extend {
740 addr,
741 port,
742 handshake,
743 rsaid,
744 })
745 }
746 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
747 w.write(&self.addr)?;
748 w.write_u16(self.port);
749 w.write_all(&self.handshake[..]);
750 w.write(&self.rsaid)?;
751 Ok(())
752 }
753}
754
755#[derive(Debug, Clone, Deftly)]
761#[derive_deftly(HasMemoryCost)]
762pub struct Extended {
763 handshake: Vec<u8>,
765}
766impl Extended {
767 pub fn new(handshake: Vec<u8>) -> Self {
769 Extended { handshake }
770 }
771}
772impl Body for Extended {
773 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
774 let handshake = r.take(TAP_S_HANDSHAKE_LEN)?.into();
775 Ok(Extended { handshake })
776 }
777 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
778 w.write_all(&self.handshake);
779 Ok(())
780 }
781}
782
783#[derive(Debug, Clone, Deftly)]
798#[derive_deftly(HasMemoryCost)]
799pub struct Extend2 {
800 linkspec: Vec<EncodedLinkSpec>,
806 handshake_type: HandshakeType,
808 handshake: Vec<u8>,
810}
811impl Extend2 {
812 pub fn new(
814 linkspec: Vec<EncodedLinkSpec>,
815 handshake_type: HandshakeType,
816 handshake: Vec<u8>,
817 ) -> Self {
818 Extend2 {
819 linkspec,
820 handshake_type,
821 handshake,
822 }
823 }
824
825 pub fn handshake_type(&self) -> HandshakeType {
827 self.handshake_type
828 }
829
830 pub fn handshake(&self) -> &[u8] {
832 &self.handshake[..]
833 }
834}
835
836impl Body for Extend2 {
837 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
838 let n = r.take_u8()?;
839 let linkspec = r.extract_n(n as usize)?;
840 let handshake_type = r.take_u16()?.into();
841 let hlen = r.take_u16()?;
842 let handshake = r.take(hlen as usize)?.into();
843 Ok(Extend2 {
844 linkspec,
845 handshake_type,
846 handshake,
847 })
848 }
849 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
850 let n_linkspecs: u8 = self
851 .linkspec
852 .len()
853 .try_into()
854 .map_err(|_| EncodeError::BadLengthValue)?;
855 w.write_u8(n_linkspecs);
856 for ls in &self.linkspec {
857 w.write(ls)?;
858 }
859 w.write_u16(self.handshake_type.into());
860 let handshake_len: u16 = self
861 .handshake
862 .len()
863 .try_into()
864 .map_err(|_| EncodeError::BadLengthValue)?;
865 w.write_u16(handshake_len);
866 w.write_all(&self.handshake[..]);
867 Ok(())
868 }
869}
870
871#[derive(Debug, Clone, Deftly)]
877#[derive_deftly(HasMemoryCost)]
878pub struct Extended2 {
879 handshake: Vec<u8>,
882}
883impl Extended2 {
884 pub fn new(handshake: Vec<u8>) -> Self {
886 Extended2 { handshake }
887 }
888 pub fn into_body(self) -> Vec<u8> {
890 self.handshake
891 }
892}
893impl Body for Extended2 {
894 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
895 let hlen = r.take_u16()?;
896 let handshake = r.take(hlen as usize)?;
897 Ok(Extended2 {
898 handshake: handshake.into(),
899 })
900 }
901 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
902 let handshake_len: u16 = self
903 .handshake
904 .len()
905 .try_into()
906 .map_err(|_| EncodeError::BadLengthValue)?;
907 w.write_u16(handshake_len);
908 w.write_all(&self.handshake[..]);
909 Ok(())
910 }
911}
912
913#[derive(Debug, Clone, Deftly)]
921#[derive_deftly(HasMemoryCost)]
922pub struct Truncated {
923 reason: DestroyReason,
925}
926impl Truncated {
927 pub fn new(reason: DestroyReason) -> Self {
929 Truncated { reason }
930 }
931 pub fn reason(self) -> DestroyReason {
933 self.reason
934 }
935}
936impl Body for Truncated {
937 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
938 Ok(Truncated {
939 reason: r.take_u8()?.into(),
940 })
941 }
942 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
943 w.write_u8(self.reason.into());
944 Ok(())
945 }
946}
947
948#[derive(Debug, Clone, Deftly)]
955#[derive_deftly(HasMemoryCost)]
956pub struct Resolve {
957 query: Vec<u8>,
959}
960impl Resolve {
961 pub fn new(s: &str) -> Self {
963 Resolve {
964 query: s.as_bytes().into(),
965 }
966 }
967 pub fn new_reverse(addr: &IpAddr) -> Self {
969 let query = match addr {
970 IpAddr::V4(v4) => {
971 let [a, b, c, d] = v4.octets();
972 format!("{}.{}.{}.{}.in-addr.arpa", d, c, b, a)
973 }
974 IpAddr::V6(v6) => {
975 let mut s = String::with_capacity(72);
976 for o in v6.octets().iter().rev() {
977 let high_nybble = o >> 4;
978 let low_nybble = o & 15;
979 write!(s, "{:x}.{:x}.", low_nybble, high_nybble).unwrap();
980 }
981 write!(s, "ip6.arpa").unwrap();
982 s
983 }
984 };
985 Resolve {
986 query: query.into_bytes(),
987 }
988 }
989}
990impl Body for Resolve {
991 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
992 let query = r.take_until(0)?;
993 Ok(Resolve {
994 query: query.into(),
995 })
996 }
997 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
998 w.write_all(&self.query[..]);
999 w.write_u8(0);
1000 Ok(())
1001 }
1002}
1003
1004#[derive(Debug, Clone, Eq, PartialEq, Deftly)]
1006#[derive_deftly(HasMemoryCost)]
1007#[non_exhaustive]
1008pub enum ResolvedVal {
1009 Ip(IpAddr),
1011 Hostname(Vec<u8>),
1013 TransientError,
1015 NontransientError,
1017 Unrecognized(u8, Vec<u8>),
1019}
1020
1021const RES_HOSTNAME: u8 = 0;
1023const RES_IPV4: u8 = 4;
1025const RES_IPV6: u8 = 6;
1027const RES_ERR_TRANSIENT: u8 = 0xF0;
1029const RES_ERR_NONTRANSIENT: u8 = 0xF1;
1031
1032impl Readable for ResolvedVal {
1033 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1034 fn res_len(tp: u8) -> Option<usize> {
1037 match tp {
1038 RES_IPV4 => Some(4),
1039 RES_IPV6 => Some(16),
1040 _ => None,
1041 }
1042 }
1043 let tp = r.take_u8()?;
1044 let len = r.take_u8()? as usize;
1045 if let Some(expected_len) = res_len(tp) {
1046 if len != expected_len {
1047 return Err(Error::InvalidMessage(
1048 "Wrong length for RESOLVED answer".into(),
1049 ));
1050 }
1051 }
1052 Ok(match tp {
1053 RES_HOSTNAME => Self::Hostname(r.take(len)?.into()),
1054 RES_IPV4 => Self::Ip(IpAddr::V4(r.extract()?)),
1055 RES_IPV6 => Self::Ip(IpAddr::V6(r.extract()?)),
1056 RES_ERR_TRANSIENT => {
1057 r.advance(len)?;
1058 Self::TransientError
1059 }
1060 RES_ERR_NONTRANSIENT => {
1061 r.advance(len)?;
1062 Self::NontransientError
1063 }
1064 _ => Self::Unrecognized(tp, r.take(len)?.into()),
1065 })
1066 }
1067}
1068
1069impl Writeable for ResolvedVal {
1070 fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
1071 match self {
1072 Self::Hostname(h) => {
1073 w.write_u8(RES_HOSTNAME);
1074 let h_len: u8 = h
1075 .len()
1076 .try_into()
1077 .map_err(|_| EncodeError::BadLengthValue)?;
1078 w.write_u8(h_len);
1079 w.write_all(&h[..]);
1080 }
1081 Self::Ip(IpAddr::V4(a)) => {
1082 w.write_u8(RES_IPV4);
1083 w.write_u8(4); w.write(a)?;
1085 }
1086 Self::Ip(IpAddr::V6(a)) => {
1087 w.write_u8(RES_IPV6);
1088 w.write_u8(16); w.write(a)?;
1090 }
1091 Self::TransientError => {
1092 w.write_u8(RES_ERR_TRANSIENT);
1093 w.write_u8(0); }
1095 Self::NontransientError => {
1096 w.write_u8(RES_ERR_NONTRANSIENT);
1097 w.write_u8(0); }
1099 Self::Unrecognized(tp, v) => {
1100 w.write_u8(*tp);
1101 let v_len: u8 = v
1102 .len()
1103 .try_into()
1104 .map_err(|_| EncodeError::BadLengthValue)?;
1105 w.write_u8(v_len);
1106 w.write_all(&v[..]);
1107 }
1108 }
1109 Ok(())
1110 }
1111}
1112
1113#[derive(Debug, Clone, Deftly)]
1118#[derive_deftly(HasMemoryCost)]
1119pub struct Resolved {
1120 answers: Vec<(ResolvedVal, u32)>,
1122}
1123impl Resolved {
1124 pub fn new_empty() -> Self {
1126 Resolved {
1127 answers: Vec::new(),
1128 }
1129 }
1130 pub fn new_err(transient: bool, ttl: u32) -> Self {
1135 let mut res = Self::new_empty();
1136 let err = if transient {
1137 ResolvedVal::TransientError
1138 } else {
1139 ResolvedVal::NontransientError
1140 };
1141 res.add_answer(err, ttl);
1142 res
1143 }
1144 pub fn add_answer(&mut self, answer: ResolvedVal, ttl: u32) {
1146 self.answers.push((answer, ttl));
1147 }
1148
1149 pub fn into_answers(self) -> Vec<(ResolvedVal, u32)> {
1157 self.answers
1158 }
1159}
1160impl Body for Resolved {
1161 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1162 let mut answers = Vec::new();
1163 while r.remaining() > 0 {
1164 let rv = r.extract()?;
1165 let ttl = r.take_u32()?;
1166 answers.push((rv, ttl));
1167 }
1168 Ok(Resolved { answers })
1169 }
1170 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1171 for (rv, ttl) in &self.answers {
1172 w.write(rv)?;
1173 w.write_u32(*ttl);
1174 }
1175 Ok(())
1176 }
1177}
1178
1179#[derive(Debug, Clone, Deftly)]
1183#[derive_deftly(HasMemoryCost)]
1184pub struct Unrecognized {
1185 cmd: RelayCmd,
1187 body: Vec<u8>,
1189}
1190
1191impl Unrecognized {
1192 pub fn new<B>(cmd: RelayCmd, body: B) -> Self
1194 where
1195 B: Into<Vec<u8>>,
1196 {
1197 let body = body.into();
1198 Unrecognized { cmd, body }
1199 }
1200
1201 pub fn cmd(&self) -> RelayCmd {
1203 self.cmd
1204 }
1205 pub fn decode_with_cmd(cmd: RelayCmd, r: &mut Reader<'_>) -> Result<Self> {
1207 let mut r = Unrecognized::decode_from_reader(r)?;
1208 r.cmd = cmd;
1209 Ok(r)
1210 }
1211}
1212
1213impl Body for Unrecognized {
1214 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1215 Ok(Unrecognized {
1216 cmd: 0.into(),
1217 body: r.take(r.remaining())?.into(),
1218 })
1219 }
1220 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1221 w.write_all(&self.body[..]);
1222 Ok(())
1223 }
1224}
1225
1226macro_rules! empty_body {
1228 {
1229 $(#[$meta:meta])*
1230 pub struct $name:ident {}
1231 } => {
1232 $(#[$meta])*
1233 #[derive(Clone,Debug,Default,derive_deftly::Deftly)]
1234 #[derive_deftly(tor_memquota::HasMemoryCost)]
1235 #[non_exhaustive]
1236 pub struct $name {}
1237 impl $crate::relaycell::msg::Body for $name {
1238 fn decode_from_reader(_r: &mut Reader<'_>) -> Result<Self> {
1239 Ok(Self::default())
1240 }
1241 fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
1242 Ok(())
1243 }
1244 }
1245 }
1246}
1247pub(crate) use empty_body;
1248
1249empty_body! {
1250 pub struct Drop {}
1252}
1253empty_body! {
1254 pub struct Truncate {}
1256}
1257empty_body! {
1258 pub struct BeginDir {}
1260}
1261
1262macro_rules! msg_impl_relaymsg {
1272 ($($body:ident),* $(,)?) =>
1273 {paste::paste!{
1274 $(impl crate::relaycell::RelayMsg for $body {
1275 fn cmd(&self) -> crate::relaycell::RelayCmd { crate::relaycell::RelayCmd::[< $body:snake:upper >] }
1276 fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1277 crate::relaycell::msg::Body::encode_onto(self, w)
1278 }
1279 fn decode_from_reader(cmd: RelayCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1280 if cmd != crate::relaycell::RelayCmd::[< $body:snake:upper >] {
1281 return Err(tor_bytes::Error::InvalidMessage(
1282 format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1283 ));
1284 }
1285 crate::relaycell::msg::Body::decode_from_reader(r)
1286 }
1287 }
1288
1289 impl TryFrom<AnyRelayMsg> for $body {
1290 type Error = crate::Error;
1291 fn try_from(msg: AnyRelayMsg) -> crate::Result<$body> {
1292 use crate::relaycell::RelayMsg;
1293 match msg {
1294 AnyRelayMsg::$body(b) => Ok(b),
1295 _ => Err(crate::Error::CircProto(format!("Expected {}; got {}" ,
1296 stringify!([<$body:snake:upper>]),
1297 msg.cmd())) ),
1298 }
1299 }
1300 }
1301 )*
1302 }}
1303}
1304
1305msg_impl_relaymsg!(
1306 Begin, Data, End, Connected, Sendme, Extend, Extended, Extend2, Extended2, Truncate, Truncated,
1307 Drop, Resolve, Resolved, BeginDir,
1308);
1309
1310#[cfg(feature = "experimental-udp")]
1311msg_impl_relaymsg!(ConnectUdp, ConnectedUdp, Datagram);
1312
1313#[cfg(feature = "hs")]
1314msg_impl_relaymsg!(
1315 EstablishIntro,
1316 EstablishRendezvous,
1317 Introduce1,
1318 Introduce2,
1319 Rendezvous1,
1320 Rendezvous2,
1321 IntroEstablished,
1322 RendezvousEstablished,
1323 IntroduceAck,
1324);
1325
1326#[cfg(feature = "conflux")]
1327msg_impl_relaymsg!(ConfluxSwitch);