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 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_V0: usize = CELL_DATA_LEN - 11;
323
324 pub const MAXLEN_V1: usize = CELL_DATA_LEN - 21;
328
329 pub const MAXLEN: usize = Data::MAXLEN_V0;
335
336 pub fn new(inp: &[u8]) -> crate::Result<Self> {
340 if inp.len() > Data::MAXLEN {
341 return Err(crate::Error::CantEncode("Data message too long"));
342 }
343 if inp.is_empty() {
344 return Err(crate::Error::CantEncode("Empty data message"));
345 }
346 Ok(Self::new_unchecked(inp.into()))
347 }
348
349 pub fn try_split_from(version: RelayCellFormat, inp: &[u8]) -> Option<(Self, &[u8])> {
357 if inp.is_empty() {
358 return None;
359 }
360 let upper_bound = Self::max_body_len(version);
361 let len = std::cmp::min(inp.len(), upper_bound);
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
375 pub fn max_body_len(format: RelayCellFormat) -> usize {
378 match format {
379 RelayCellFormat::V0 => Self::MAXLEN_V0,
380 RelayCellFormat::V1 => Self::MAXLEN_V1,
381 }
382 }
383}
384impl From<Data> for Vec<u8> {
385 fn from(data: Data) -> Vec<u8> {
386 data.body
387 }
388}
389impl AsRef<[u8]> for Data {
390 fn as_ref(&self) -> &[u8] {
391 &self.body[..]
392 }
393}
394
395impl Body for Data {
396 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
397 if r.remaining() == 0 {
398 return Err(Error::InvalidMessage("Empty DATA message".into()));
399 }
400 Ok(Data {
401 body: r.take(r.remaining())?.into(),
402 })
403 }
404 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
405 w.write_all(&self.body);
406 Ok(())
407 }
408}
409
410#[derive(Debug, Clone, Deftly)]
416#[derive_deftly(HasMemoryCost)]
417pub struct End {
418 reason: EndReason,
420 addr: Option<(IpAddr, u32)>,
423}
424
425caret_int! {
426 #[derive(Deftly)]
428 #[derive_deftly(HasMemoryCost)]
429 pub struct EndReason(u8) {
430 MISC = 1,
434 RESOLVEFAILED = 2,
436 CONNECTREFUSED = 3,
438 EXITPOLICY = 4,
440 DESTROY = 5,
442 DONE = 6,
444 TIMEOUT = 7,
446 NOROUTE = 8,
448 HIBERNATING = 9,
450 INTERNAL = 10,
452 RESOURCELIMIT = 11,
454 CONNRESET = 12,
456 TORPROTOCOL = 13,
458 NOTDIRECTORY = 14,
460 }
461}
462
463impl tor_error::HasKind for EndReason {
464 fn kind(&self) -> tor_error::ErrorKind {
465 use tor_error::ErrorKind as EK;
466 use EndReason as E;
467 match *self {
468 E::MISC => EK::RemoteStreamError,
469 E::RESOLVEFAILED => EK::RemoteHostResolutionFailed,
470 E::CONNECTREFUSED => EK::RemoteConnectionRefused,
471 E::EXITPOLICY => EK::ExitPolicyRejected,
472 E::DESTROY => EK::CircuitCollapse,
473 E::DONE => EK::RemoteStreamClosed,
474 E::TIMEOUT => EK::ExitTimeout,
475 E::NOROUTE => EK::RemoteNetworkFailed,
476 E::RESOURCELIMIT | E::HIBERNATING => EK::RelayTooBusy,
477 E::INTERNAL | E::TORPROTOCOL | E::NOTDIRECTORY => EK::TorProtocolViolation,
478 E::CONNRESET => EK::RemoteStreamReset,
479 _ => EK::RemoteStreamError,
480 }
481 }
482}
483
484impl End {
485 pub fn new_misc() -> Self {
489 End {
490 reason: EndReason::MISC,
491 addr: None,
492 }
493 }
494 pub fn new_with_reason(reason: EndReason) -> Self {
496 End { reason, addr: None }
497 }
498 pub fn new_exitpolicy(addr: IpAddr, ttl: u32) -> Self {
501 End {
502 reason: EndReason::EXITPOLICY,
503 addr: Some((addr, ttl)),
504 }
505 }
506 pub fn reason(&self) -> EndReason {
508 self.reason
509 }
510}
511impl Body for End {
512 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
513 if r.remaining() == 0 {
514 return Ok(End {
515 reason: EndReason::MISC,
516 addr: None,
517 });
518 }
519 let reason = r.take_u8()?.into();
520 if reason == EndReason::EXITPOLICY {
521 let addr = match r.remaining() {
522 4 | 8 => IpAddr::V4(r.extract()?),
523 16 | 20 => IpAddr::V6(r.extract()?),
524 _ => {
525 return Ok(End { reason, addr: None });
527 }
528 };
529 let ttl = if r.remaining() == 4 {
530 r.take_u32()?
531 } else {
532 u32::MAX
533 };
534 Ok(End {
535 reason,
536 addr: Some((addr, ttl)),
537 })
538 } else {
539 Ok(End { reason, addr: None })
540 }
541 }
542 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
543 w.write_u8(self.reason.into());
544 if let (EndReason::EXITPOLICY, Some((addr, ttl))) = (self.reason, self.addr) {
545 match addr {
546 IpAddr::V4(v4) => w.write(&v4)?,
547 IpAddr::V6(v6) => w.write(&v6)?,
548 }
549 w.write_u32(ttl);
550 }
551 Ok(())
552 }
553}
554
555impl From<EndReason> for std::io::ErrorKind {
556 fn from(e: EndReason) -> Self {
557 use std::io::ErrorKind::*;
558 match e {
559 EndReason::RESOLVEFAILED => NotFound,
560 EndReason::CONNECTREFUSED => ConnectionRefused,
561 EndReason::EXITPOLICY => ConnectionRefused,
562 EndReason::DESTROY => ConnectionAborted,
563 EndReason::DONE => UnexpectedEof,
564 EndReason::TIMEOUT => TimedOut,
565 EndReason::HIBERNATING => ConnectionRefused,
566 EndReason::RESOURCELIMIT => ConnectionRefused,
567 EndReason::CONNRESET => ConnectionReset,
568 EndReason::TORPROTOCOL => InvalidData,
569 EndReason::NOTDIRECTORY => ConnectionRefused,
570 EndReason::INTERNAL | EndReason::NOROUTE | EndReason::MISC => Other,
571 _ => Other,
572 }
573 }
574}
575
576#[derive(Debug, Clone, Deftly)]
583#[derive_deftly(HasMemoryCost)]
584pub struct Connected {
585 addr: Option<(IpAddr, u32)>,
587}
588impl Connected {
589 pub fn new_empty() -> Self {
591 Connected { addr: None }
592 }
593 pub fn new_with_addr(addr: IpAddr, ttl: u32) -> Self {
595 Connected {
596 addr: Some((addr, ttl)),
597 }
598 }
599}
600impl Body for Connected {
601 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
602 if r.remaining() == 0 {
603 return Ok(Connected { addr: None });
604 }
605 let ipv4 = r.take_u32()?;
606 let addr = if ipv4 == 0 {
607 if r.take_u8()? != 6 {
608 return Err(Error::InvalidMessage(
609 "Invalid address type in CONNECTED cell".into(),
610 ));
611 }
612 IpAddr::V6(r.extract()?)
613 } else {
614 IpAddr::V4(ipv4.into())
615 };
616 let ttl = r.take_u32()?;
617
618 Ok(Connected {
619 addr: Some((addr, ttl)),
620 })
621 }
622 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
623 if let Some((addr, ttl)) = self.addr {
624 match addr {
625 IpAddr::V4(v4) => w.write(&v4)?,
626 IpAddr::V6(v6) => {
627 w.write_u32(0);
628 w.write_u8(6);
629 w.write(&v6)?;
630 }
631 }
632 w.write_u32(ttl);
633 }
634 Ok(())
635 }
636}
637
638#[derive(Debug, Clone, Deftly)]
655#[derive_deftly(HasMemoryCost)]
656pub struct Sendme {
657 digest: Option<Vec<u8>>,
659}
660impl Sendme {
661 pub fn new_empty() -> Self {
666 Sendme { digest: None }
667 }
668 pub fn new_tag(x: [u8; 20]) -> Self {
670 Sendme {
671 digest: Some(x.into()),
672 }
673 }
674 pub fn into_tag(self) -> Option<Vec<u8>> {
676 self.digest
677 }
678}
679impl Body for Sendme {
680 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
681 let digest = if r.remaining() == 0 {
682 None
683 } else {
684 let ver = r.take_u8()?;
685 match ver {
686 0 => None,
687 1 => {
688 let dlen = r.take_u16()?;
689 Some(r.take(dlen as usize)?.into())
690 }
691 _ => {
692 return Err(Error::InvalidMessage("Unrecognized SENDME version.".into()));
693 }
694 }
695 };
696 Ok(Sendme { digest })
697 }
698 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
699 match self.digest {
700 None => (),
701 Some(x) => {
702 w.write_u8(1);
703 let bodylen: u16 = x
704 .len()
705 .try_into()
706 .map_err(|_| EncodeError::BadLengthValue)?;
707 w.write_u16(bodylen);
708 w.write_all(&x);
709 }
710 }
711 Ok(())
712 }
713}
714
715#[derive(Debug, Clone, Deftly)]
720#[derive_deftly(HasMemoryCost)]
721pub struct Extend {
722 addr: Ipv4Addr,
724 port: u16,
726 handshake: Vec<u8>,
728 rsaid: RsaIdentity,
730}
731impl Extend {
732 pub fn new(addr: Ipv4Addr, port: u16, handshake: Vec<u8>, rsaid: RsaIdentity) -> Self {
734 Extend {
735 addr,
736 port,
737 handshake,
738 rsaid,
739 }
740 }
741}
742impl Body for Extend {
743 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
744 let addr = r.extract()?;
745 let port = r.take_u16()?;
746 let handshake = r.take(TAP_C_HANDSHAKE_LEN)?.into();
747 let rsaid = r.extract()?;
748 Ok(Extend {
749 addr,
750 port,
751 handshake,
752 rsaid,
753 })
754 }
755 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
756 w.write(&self.addr)?;
757 w.write_u16(self.port);
758 w.write_all(&self.handshake[..]);
759 w.write(&self.rsaid)?;
760 Ok(())
761 }
762}
763
764#[derive(Debug, Clone, Deftly)]
770#[derive_deftly(HasMemoryCost)]
771pub struct Extended {
772 handshake: Vec<u8>,
774}
775impl Extended {
776 pub fn new(handshake: Vec<u8>) -> Self {
778 Extended { handshake }
779 }
780}
781impl Body for Extended {
782 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
783 let handshake = r.take(TAP_S_HANDSHAKE_LEN)?.into();
784 Ok(Extended { handshake })
785 }
786 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
787 w.write_all(&self.handshake);
788 Ok(())
789 }
790}
791
792#[derive(Debug, Clone, Deftly)]
807#[derive_deftly(HasMemoryCost)]
808pub struct Extend2 {
809 linkspec: Vec<EncodedLinkSpec>,
815 handshake_type: HandshakeType,
817 handshake: Vec<u8>,
819}
820impl Extend2 {
821 pub fn new(
823 linkspec: Vec<EncodedLinkSpec>,
824 handshake_type: HandshakeType,
825 handshake: Vec<u8>,
826 ) -> Self {
827 Extend2 {
828 linkspec,
829 handshake_type,
830 handshake,
831 }
832 }
833
834 pub fn handshake_type(&self) -> HandshakeType {
836 self.handshake_type
837 }
838
839 pub fn handshake(&self) -> &[u8] {
841 &self.handshake[..]
842 }
843}
844
845impl Body for Extend2 {
846 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
847 let n = r.take_u8()?;
848 let linkspec = r.extract_n(n as usize)?;
849 let handshake_type = r.take_u16()?.into();
850 let hlen = r.take_u16()?;
851 let handshake = r.take(hlen as usize)?.into();
852 Ok(Extend2 {
853 linkspec,
854 handshake_type,
855 handshake,
856 })
857 }
858 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
859 let n_linkspecs: u8 = self
860 .linkspec
861 .len()
862 .try_into()
863 .map_err(|_| EncodeError::BadLengthValue)?;
864 w.write_u8(n_linkspecs);
865 for ls in &self.linkspec {
866 w.write(ls)?;
867 }
868 w.write_u16(self.handshake_type.into());
869 let handshake_len: u16 = self
870 .handshake
871 .len()
872 .try_into()
873 .map_err(|_| EncodeError::BadLengthValue)?;
874 w.write_u16(handshake_len);
875 w.write_all(&self.handshake[..]);
876 Ok(())
877 }
878}
879
880#[derive(Debug, Clone, Deftly)]
886#[derive_deftly(HasMemoryCost)]
887pub struct Extended2 {
888 handshake: Vec<u8>,
891}
892impl Extended2 {
893 pub fn new(handshake: Vec<u8>) -> Self {
895 Extended2 { handshake }
896 }
897 pub fn into_body(self) -> Vec<u8> {
899 self.handshake
900 }
901}
902impl Body for Extended2 {
903 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
904 let hlen = r.take_u16()?;
905 let handshake = r.take(hlen as usize)?;
906 Ok(Extended2 {
907 handshake: handshake.into(),
908 })
909 }
910 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
911 let handshake_len: u16 = self
912 .handshake
913 .len()
914 .try_into()
915 .map_err(|_| EncodeError::BadLengthValue)?;
916 w.write_u16(handshake_len);
917 w.write_all(&self.handshake[..]);
918 Ok(())
919 }
920}
921
922#[derive(Debug, Clone, Deftly)]
930#[derive_deftly(HasMemoryCost)]
931pub struct Truncated {
932 reason: DestroyReason,
934}
935impl Truncated {
936 pub fn new(reason: DestroyReason) -> Self {
938 Truncated { reason }
939 }
940 pub fn reason(self) -> DestroyReason {
942 self.reason
943 }
944}
945impl Body for Truncated {
946 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
947 Ok(Truncated {
948 reason: r.take_u8()?.into(),
949 })
950 }
951 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
952 w.write_u8(self.reason.into());
953 Ok(())
954 }
955}
956
957#[derive(Debug, Clone, Deftly)]
964#[derive_deftly(HasMemoryCost)]
965pub struct Resolve {
966 query: Vec<u8>,
968}
969impl Resolve {
970 pub fn new(s: &str) -> Self {
972 Resolve {
973 query: s.as_bytes().into(),
974 }
975 }
976 pub fn new_reverse(addr: &IpAddr) -> Self {
978 let query = match addr {
979 IpAddr::V4(v4) => {
980 let [a, b, c, d] = v4.octets();
981 format!("{}.{}.{}.{}.in-addr.arpa", d, c, b, a)
982 }
983 IpAddr::V6(v6) => {
984 let mut s = String::with_capacity(72);
985 for o in v6.octets().iter().rev() {
986 let high_nybble = o >> 4;
987 let low_nybble = o & 15;
988 write!(s, "{:x}.{:x}.", low_nybble, high_nybble).unwrap();
989 }
990 write!(s, "ip6.arpa").unwrap();
991 s
992 }
993 };
994 Resolve {
995 query: query.into_bytes(),
996 }
997 }
998}
999impl Body for Resolve {
1000 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1001 let query = r.take_until(0)?;
1002 Ok(Resolve {
1003 query: query.into(),
1004 })
1005 }
1006 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1007 w.write_all(&self.query[..]);
1008 w.write_u8(0);
1009 Ok(())
1010 }
1011}
1012
1013#[derive(Debug, Clone, Eq, PartialEq, Deftly)]
1015#[derive_deftly(HasMemoryCost)]
1016#[non_exhaustive]
1017pub enum ResolvedVal {
1018 Ip(IpAddr),
1020 Hostname(Vec<u8>),
1022 TransientError,
1024 NontransientError,
1026 Unrecognized(u8, Vec<u8>),
1028}
1029
1030const RES_HOSTNAME: u8 = 0;
1032const RES_IPV4: u8 = 4;
1034const RES_IPV6: u8 = 6;
1036const RES_ERR_TRANSIENT: u8 = 0xF0;
1038const RES_ERR_NONTRANSIENT: u8 = 0xF1;
1040
1041impl Readable for ResolvedVal {
1042 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1043 fn res_len(tp: u8) -> Option<usize> {
1046 match tp {
1047 RES_IPV4 => Some(4),
1048 RES_IPV6 => Some(16),
1049 _ => None,
1050 }
1051 }
1052 let tp = r.take_u8()?;
1053 let len = r.take_u8()? as usize;
1054 if let Some(expected_len) = res_len(tp) {
1055 if len != expected_len {
1056 return Err(Error::InvalidMessage(
1057 "Wrong length for RESOLVED answer".into(),
1058 ));
1059 }
1060 }
1061 Ok(match tp {
1062 RES_HOSTNAME => Self::Hostname(r.take(len)?.into()),
1063 RES_IPV4 => Self::Ip(IpAddr::V4(r.extract()?)),
1064 RES_IPV6 => Self::Ip(IpAddr::V6(r.extract()?)),
1065 RES_ERR_TRANSIENT => {
1066 r.advance(len)?;
1067 Self::TransientError
1068 }
1069 RES_ERR_NONTRANSIENT => {
1070 r.advance(len)?;
1071 Self::NontransientError
1072 }
1073 _ => Self::Unrecognized(tp, r.take(len)?.into()),
1074 })
1075 }
1076}
1077
1078impl Writeable for ResolvedVal {
1079 fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
1080 match self {
1081 Self::Hostname(h) => {
1082 w.write_u8(RES_HOSTNAME);
1083 let h_len: u8 = h
1084 .len()
1085 .try_into()
1086 .map_err(|_| EncodeError::BadLengthValue)?;
1087 w.write_u8(h_len);
1088 w.write_all(&h[..]);
1089 }
1090 Self::Ip(IpAddr::V4(a)) => {
1091 w.write_u8(RES_IPV4);
1092 w.write_u8(4); w.write(a)?;
1094 }
1095 Self::Ip(IpAddr::V6(a)) => {
1096 w.write_u8(RES_IPV6);
1097 w.write_u8(16); w.write(a)?;
1099 }
1100 Self::TransientError => {
1101 w.write_u8(RES_ERR_TRANSIENT);
1102 w.write_u8(0); }
1104 Self::NontransientError => {
1105 w.write_u8(RES_ERR_NONTRANSIENT);
1106 w.write_u8(0); }
1108 Self::Unrecognized(tp, v) => {
1109 w.write_u8(*tp);
1110 let v_len: u8 = v
1111 .len()
1112 .try_into()
1113 .map_err(|_| EncodeError::BadLengthValue)?;
1114 w.write_u8(v_len);
1115 w.write_all(&v[..]);
1116 }
1117 }
1118 Ok(())
1119 }
1120}
1121
1122#[derive(Debug, Clone, Deftly)]
1127#[derive_deftly(HasMemoryCost)]
1128pub struct Resolved {
1129 answers: Vec<(ResolvedVal, u32)>,
1131}
1132impl Resolved {
1133 pub fn new_empty() -> Self {
1135 Resolved {
1136 answers: Vec::new(),
1137 }
1138 }
1139 pub fn new_err(transient: bool, ttl: u32) -> Self {
1144 let mut res = Self::new_empty();
1145 let err = if transient {
1146 ResolvedVal::TransientError
1147 } else {
1148 ResolvedVal::NontransientError
1149 };
1150 res.add_answer(err, ttl);
1151 res
1152 }
1153 pub fn add_answer(&mut self, answer: ResolvedVal, ttl: u32) {
1155 self.answers.push((answer, ttl));
1156 }
1157
1158 pub fn into_answers(self) -> Vec<(ResolvedVal, u32)> {
1166 self.answers
1167 }
1168}
1169impl Body for Resolved {
1170 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1171 let mut answers = Vec::new();
1172 while r.remaining() > 0 {
1173 let rv = r.extract()?;
1174 let ttl = r.take_u32()?;
1175 answers.push((rv, ttl));
1176 }
1177 Ok(Resolved { answers })
1178 }
1179 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1180 for (rv, ttl) in &self.answers {
1181 w.write(rv)?;
1182 w.write_u32(*ttl);
1183 }
1184 Ok(())
1185 }
1186}
1187
1188#[derive(Debug, Clone, Deftly)]
1192#[derive_deftly(HasMemoryCost)]
1193pub struct Unrecognized {
1194 cmd: RelayCmd,
1196 body: Vec<u8>,
1198}
1199
1200impl Unrecognized {
1201 pub fn new<B>(cmd: RelayCmd, body: B) -> Self
1203 where
1204 B: Into<Vec<u8>>,
1205 {
1206 let body = body.into();
1207 Unrecognized { cmd, body }
1208 }
1209
1210 pub fn cmd(&self) -> RelayCmd {
1212 self.cmd
1213 }
1214 pub fn decode_with_cmd(cmd: RelayCmd, r: &mut Reader<'_>) -> Result<Self> {
1216 let mut r = Unrecognized::decode_from_reader(r)?;
1217 r.cmd = cmd;
1218 Ok(r)
1219 }
1220}
1221
1222impl Body for Unrecognized {
1223 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1224 Ok(Unrecognized {
1225 cmd: 0.into(),
1226 body: r.take(r.remaining())?.into(),
1227 })
1228 }
1229 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1230 w.write_all(&self.body[..]);
1231 Ok(())
1232 }
1233}
1234
1235macro_rules! empty_body {
1237 {
1238 $(#[$meta:meta])*
1239 pub struct $name:ident {}
1240 } => {
1241 $(#[$meta])*
1242 #[derive(Clone,Debug,Default,derive_deftly::Deftly)]
1243 #[derive_deftly(tor_memquota::HasMemoryCost)]
1244 #[non_exhaustive]
1245 pub struct $name {}
1246 impl $crate::relaycell::msg::Body for $name {
1247 fn decode_from_reader(_r: &mut Reader<'_>) -> Result<Self> {
1248 Ok(Self::default())
1249 }
1250 fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
1251 Ok(())
1252 }
1253 }
1254 }
1255}
1256pub(crate) use empty_body;
1257
1258empty_body! {
1259 pub struct Drop {}
1261}
1262empty_body! {
1263 pub struct Truncate {}
1265}
1266empty_body! {
1267 pub struct BeginDir {}
1269}
1270
1271macro_rules! msg_impl_relaymsg {
1281 ($($body:ident),* $(,)?) =>
1282 {paste::paste!{
1283 $(impl crate::relaycell::RelayMsg for $body {
1284 fn cmd(&self) -> crate::relaycell::RelayCmd { crate::relaycell::RelayCmd::[< $body:snake:upper >] }
1285 fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1286 crate::relaycell::msg::Body::encode_onto(self, w)
1287 }
1288 fn decode_from_reader(cmd: RelayCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1289 if cmd != crate::relaycell::RelayCmd::[< $body:snake:upper >] {
1290 return Err(tor_bytes::Error::InvalidMessage(
1291 format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1292 ));
1293 }
1294 crate::relaycell::msg::Body::decode_from_reader(r)
1295 }
1296 }
1297
1298 impl TryFrom<AnyRelayMsg> for $body {
1299 type Error = crate::Error;
1300 fn try_from(msg: AnyRelayMsg) -> crate::Result<$body> {
1301 use crate::relaycell::RelayMsg;
1302 match msg {
1303 AnyRelayMsg::$body(b) => Ok(b),
1304 _ => Err(crate::Error::CircProto(format!("Expected {}; got {}" ,
1305 stringify!([<$body:snake:upper>]),
1306 msg.cmd())) ),
1307 }
1308 }
1309 }
1310 )*
1311 }}
1312}
1313
1314msg_impl_relaymsg!(
1315 Begin, Data, End, Connected, Sendme, Extend, Extended, Extend2, Extended2, Truncate, Truncated,
1316 Drop, Resolve, Resolved, BeginDir,
1317);
1318
1319#[cfg(feature = "experimental-udp")]
1320msg_impl_relaymsg!(ConnectUdp, ConnectedUdp, Datagram);
1321
1322#[cfg(feature = "hs")]
1323msg_impl_relaymsg!(
1324 EstablishIntro,
1325 EstablishRendezvous,
1326 Introduce1,
1327 Introduce2,
1328 Rendezvous1,
1329 Rendezvous2,
1330 IntroEstablished,
1331 RendezvousEstablished,
1332 IntroduceAck,
1333);
1334
1335#[cfg(feature = "conflux")]
1336msg_impl_relaymsg!(ConfluxSwitch, ConfluxLink, ConfluxLinked, ConfluxLinkedAck);