1use super::flow_ctrl::{Xoff, Xon};
7use super::{RelayCellFormat, RelayCmd};
8use crate::chancell::CELL_DATA_LEN;
9use crate::chancell::msg::{
10 DestroyReason, HandshakeType, TAP_C_HANDSHAKE_LEN, TAP_S_HANDSHAKE_LEN,
11};
12use caret::caret_int;
13use derive_deftly::Deftly;
14use std::fmt::Write;
15use std::net::{IpAddr, Ipv4Addr};
16use std::num::NonZeroU8;
17use tor_bytes::{EncodeError, EncodeResult, Error, Result};
18use tor_bytes::{Readable, Reader, Writeable, Writer};
19use tor_linkspec::EncodedLinkSpec;
20use tor_llcrypto::pk::rsa::RsaIdentity;
21use tor_llcrypto::util::ct::CtByteArray;
22use tor_memquota::{derive_deftly_template_HasMemoryCost, memory_cost_structural_copy};
23
24use bitflags::bitflags;
25
26#[cfg(feature = "conflux")]
27pub use super::conflux::{ConfluxLink, ConfluxLinked, ConfluxLinkedAck, ConfluxSwitch};
28
29#[cfg(feature = "hs")]
30pub use super::hs::{
31 EstablishRendezvous, IntroEstablished, Introduce1, Introduce2, IntroduceAck, Rendezvous1,
32 Rendezvous2, RendezvousEstablished, est_intro::EstablishIntro,
33};
34#[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 Xon,
97 Xoff,
99 [feature = "hs"]
101 EstablishIntro,
102 [feature = "hs"]
104 EstablishRendezvous,
105 [feature = "hs"]
107 Introduce1,
108 [feature = "hs"]
110 Introduce2,
111 [feature = "hs"]
113 Rendezvous1,
114 [feature = "hs"]
116 Rendezvous2,
117 [feature = "hs"]
119 IntroEstablished,
120 [feature = "hs"]
122 RendezvousEstablished,
123 [feature = "hs"]
125 IntroduceAck,
126
127 _ =>
128 Unrecognized,
130 }
131}
132
133pub trait Body: Sized {
135 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self>;
137 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()>;
139}
140
141bitflags! {
142 #[derive(Clone, Copy, Debug)]
147 pub struct BeginFlags : u32 {
148 const IPV6_OKAY = (1<<0);
150 const IPV4_NOT_OKAY = (1<<1);
152 const IPV6_PREFERRED = (1<<2);
154 }
155}
156memory_cost_structural_copy!(BeginFlags);
157impl From<u32> for BeginFlags {
158 fn from(v: u32) -> Self {
159 BeginFlags::from_bits_truncate(v)
160 }
161}
162
163#[derive(Clone, Default, Copy, Debug, Eq, PartialEq)]
166#[non_exhaustive]
167pub enum IpVersionPreference {
168 Ipv4Only,
170 #[default]
172 Ipv4Preferred,
173 Ipv6Preferred,
175 Ipv6Only,
177}
178impl From<IpVersionPreference> for BeginFlags {
179 fn from(v: IpVersionPreference) -> Self {
180 use IpVersionPreference::*;
181 match v {
182 Ipv4Only => 0.into(),
183 Ipv4Preferred => BeginFlags::IPV6_OKAY,
184 Ipv6Preferred => BeginFlags::IPV6_OKAY | BeginFlags::IPV6_PREFERRED,
185 Ipv6Only => BeginFlags::IPV4_NOT_OKAY,
186 }
187 }
188}
189
190#[derive(Debug, Clone, Deftly)]
201#[derive_deftly(HasMemoryCost)]
202pub struct Begin {
203 addr: Vec<u8>,
205 port: u16,
207 flags: BeginFlags,
209}
210
211impl Begin {
212 pub fn new<F>(addr: &str, port: u16, flags: F) -> crate::Result<Self>
214 where
215 F: Into<BeginFlags>,
216 {
217 if !addr.is_ascii() {
218 return Err(crate::Error::BadStreamAddress);
219 }
220 let mut addr = addr.to_string();
221 addr.make_ascii_lowercase();
222 Ok(Begin {
223 addr: addr.into_bytes(),
224 port,
225 flags: flags.into(),
226 })
227 }
228
229 pub fn addr(&self) -> &[u8] {
231 &self.addr[..]
232 }
233
234 pub fn port(&self) -> u16 {
236 self.port
237 }
238
239 pub fn flags(&self) -> BeginFlags {
241 self.flags
242 }
243}
244
245impl Body for Begin {
246 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
247 let addr = {
248 if r.peek(1)? == b"[" {
249 r.advance(1)?;
251 let a = r.take_until(b']')?;
252 let colon = r.take_u8()?;
253 if colon != b':' {
254 return Err(Error::InvalidMessage("missing port in begin cell".into()));
255 }
256 a
257 } else {
258 r.take_until(b':')?
260 }
261 };
262 let port = r.take_until(0)?;
263 let flags = if r.remaining() >= 4 { r.take_u32()? } else { 0 };
264
265 if !addr.is_ascii() {
266 return Err(Error::InvalidMessage(
267 "target address in begin cell not ascii".into(),
268 ));
269 }
270
271 let port = std::str::from_utf8(port)
272 .map_err(|_| Error::InvalidMessage("port in begin cell not utf8".into()))?;
273
274 let port = port
275 .parse()
276 .map_err(|_| Error::InvalidMessage("port in begin cell not a valid port".into()))?;
277
278 Ok(Begin {
279 addr: addr.into(),
280 port,
281 flags: flags.into(),
282 })
283 }
284 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
285 if self.addr.contains(&b':') {
286 w.write_u8(b'[');
287 w.write_all(&self.addr[..]);
288 w.write_u8(b']');
289 } else {
290 w.write_all(&self.addr[..]);
291 }
292 w.write_u8(b':');
293 w.write_all(self.port.to_string().as_bytes());
294 w.write_u8(0);
295 if self.flags.bits() != 0 {
296 w.write_u32(self.flags.bits());
297 }
298 Ok(())
299 }
300}
301
302#[derive(Debug, Clone, Deftly)]
310#[derive_deftly(HasMemoryCost)]
311pub struct Data {
312 body: Vec<u8>,
321}
322impl Data {
323 pub const MAXLEN_V0: usize = CELL_DATA_LEN - 11;
327
328 pub const MAXLEN_V1: usize = CELL_DATA_LEN - 21;
332
333 pub const MAXLEN: usize = Data::MAXLEN_V0;
339
340 pub fn new(inp: &[u8]) -> crate::Result<Self> {
344 if inp.len() > Data::MAXLEN {
345 return Err(crate::Error::CantEncode("Data message too long"));
346 }
347 if inp.is_empty() {
348 return Err(crate::Error::CantEncode("Empty data message"));
349 }
350 Ok(Self::new_unchecked(inp.into()))
351 }
352
353 pub fn try_split_from(version: RelayCellFormat, inp: &[u8]) -> Option<(Self, &[u8])> {
361 if inp.is_empty() {
362 return None;
363 }
364 let upper_bound = Self::max_body_len(version);
365 let len = std::cmp::min(inp.len(), upper_bound);
366 let (data, remainder) = inp.split_at(len);
367 Some((Self::new_unchecked(data.into()), remainder))
368 }
369
370 fn new_unchecked(body: Vec<u8>) -> Self {
375 debug_assert!((1..=Data::MAXLEN).contains(&body.len()));
376 Data { body }
377 }
378
379 pub fn max_body_len(format: RelayCellFormat) -> usize {
382 match format {
383 RelayCellFormat::V0 => Self::MAXLEN_V0,
384 RelayCellFormat::V1 => Self::MAXLEN_V1,
385 }
386 }
387}
388impl From<Data> for Vec<u8> {
389 fn from(data: Data) -> Vec<u8> {
390 data.body
391 }
392}
393impl AsRef<[u8]> for Data {
394 fn as_ref(&self) -> &[u8] {
395 &self.body[..]
396 }
397}
398
399impl Body for Data {
400 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
401 if r.remaining() == 0 {
402 return Err(Error::InvalidMessage("Empty DATA message".into()));
403 }
404 Ok(Data {
405 body: r.take(r.remaining())?.into(),
406 })
407 }
408 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
409 w.write_all(&self.body);
410 Ok(())
411 }
412}
413
414#[derive(Debug, Clone, Deftly)]
420#[derive_deftly(HasMemoryCost)]
421pub struct End {
422 reason: EndReason,
424 addr: Option<(IpAddr, u32)>,
427}
428
429caret_int! {
430 #[derive(Deftly)]
432 #[derive_deftly(HasMemoryCost)]
433 pub struct EndReason(u8) {
434 MISC = 1,
438 RESOLVEFAILED = 2,
440 CONNECTREFUSED = 3,
442 EXITPOLICY = 4,
444 DESTROY = 5,
446 DONE = 6,
448 TIMEOUT = 7,
450 NOROUTE = 8,
452 HIBERNATING = 9,
454 INTERNAL = 10,
456 RESOURCELIMIT = 11,
458 CONNRESET = 12,
460 TORPROTOCOL = 13,
462 NOTDIRECTORY = 14,
464 }
465}
466
467impl tor_error::HasKind for EndReason {
468 fn kind(&self) -> tor_error::ErrorKind {
469 use EndReason as E;
470 use tor_error::ErrorKind as EK;
471 match *self {
472 E::MISC => EK::RemoteStreamError,
473 E::RESOLVEFAILED => EK::RemoteHostResolutionFailed,
474 E::CONNECTREFUSED => EK::RemoteConnectionRefused,
475 E::EXITPOLICY => EK::ExitPolicyRejected,
476 E::DESTROY => EK::CircuitCollapse,
477 E::DONE => EK::RemoteStreamClosed,
478 E::TIMEOUT => EK::ExitTimeout,
479 E::NOROUTE => EK::RemoteNetworkFailed,
480 E::RESOURCELIMIT | E::HIBERNATING => EK::RelayTooBusy,
481 E::INTERNAL | E::TORPROTOCOL | E::NOTDIRECTORY => EK::TorProtocolViolation,
482 E::CONNRESET => EK::RemoteStreamReset,
483 _ => EK::RemoteStreamError,
484 }
485 }
486}
487
488impl End {
489 pub fn new_misc() -> Self {
493 End {
494 reason: EndReason::MISC,
495 addr: None,
496 }
497 }
498 pub fn new_with_reason(reason: EndReason) -> Self {
500 End { reason, addr: None }
501 }
502 pub fn new_exitpolicy(addr: IpAddr, ttl: u32) -> Self {
505 End {
506 reason: EndReason::EXITPOLICY,
507 addr: Some((addr, ttl)),
508 }
509 }
510 pub fn reason(&self) -> EndReason {
512 self.reason
513 }
514}
515impl Body for End {
516 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
517 if r.remaining() == 0 {
518 return Ok(End {
519 reason: EndReason::MISC,
520 addr: None,
521 });
522 }
523 let reason = r.take_u8()?.into();
524 if reason == EndReason::EXITPOLICY {
525 let addr = match r.remaining() {
526 4 | 8 => IpAddr::V4(r.extract()?),
527 16 | 20 => IpAddr::V6(r.extract()?),
528 _ => {
529 return Ok(End { reason, addr: None });
531 }
532 };
533 let ttl = if r.remaining() == 4 {
534 r.take_u32()?
535 } else {
536 u32::MAX
537 };
538 Ok(End {
539 reason,
540 addr: Some((addr, ttl)),
541 })
542 } else {
543 Ok(End { reason, addr: None })
544 }
545 }
546 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
547 w.write_u8(self.reason.into());
548 if let (EndReason::EXITPOLICY, Some((addr, ttl))) = (self.reason, self.addr) {
549 match addr {
550 IpAddr::V4(v4) => w.write(&v4)?,
551 IpAddr::V6(v6) => w.write(&v6)?,
552 }
553 w.write_u32(ttl);
554 }
555 Ok(())
556 }
557}
558
559impl From<EndReason> for std::io::ErrorKind {
560 fn from(e: EndReason) -> Self {
561 use std::io::ErrorKind::*;
562 match e {
563 EndReason::RESOLVEFAILED => NotFound,
564 EndReason::CONNECTREFUSED => ConnectionRefused,
565 EndReason::EXITPOLICY => ConnectionRefused,
566 EndReason::DESTROY => ConnectionAborted,
567 EndReason::DONE => UnexpectedEof,
568 EndReason::TIMEOUT => TimedOut,
569 EndReason::HIBERNATING => ConnectionRefused,
570 EndReason::RESOURCELIMIT => ConnectionRefused,
571 EndReason::CONNRESET => ConnectionReset,
572 EndReason::TORPROTOCOL => InvalidData,
573 EndReason::NOTDIRECTORY => ConnectionRefused,
574 EndReason::INTERNAL | EndReason::NOROUTE | EndReason::MISC => Other,
575 _ => Other,
576 }
577 }
578}
579
580#[derive(Debug, Clone, Deftly)]
587#[derive_deftly(HasMemoryCost)]
588pub struct Connected {
589 addr: Option<(IpAddr, u32)>,
591}
592impl Connected {
593 pub fn new_empty() -> Self {
595 Connected { addr: None }
596 }
597 pub fn new_with_addr(addr: IpAddr, ttl: u32) -> Self {
599 Connected {
600 addr: Some((addr, ttl)),
601 }
602 }
603}
604impl Body for Connected {
605 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
606 if r.remaining() == 0 {
607 return Ok(Connected { addr: None });
608 }
609 let ipv4 = r.take_u32()?;
610 let addr = if ipv4 == 0 {
611 if r.take_u8()? != 6 {
612 return Err(Error::InvalidMessage(
613 "Invalid address type in CONNECTED cell".into(),
614 ));
615 }
616 IpAddr::V6(r.extract()?)
617 } else {
618 IpAddr::V4(ipv4.into())
619 };
620 let ttl = r.take_u32()?;
621
622 Ok(Connected {
623 addr: Some((addr, ttl)),
624 })
625 }
626 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
627 if let Some((addr, ttl)) = self.addr {
628 match addr {
629 IpAddr::V4(v4) => w.write(&v4)?,
630 IpAddr::V6(v6) => {
631 w.write_u32(0);
632 w.write_u8(6);
633 w.write(&v6)?;
634 }
635 }
636 w.write_u32(ttl);
637 }
638 Ok(())
639 }
640}
641
642#[derive(Debug, Clone, Copy, Eq, PartialEq, Deftly)]
647#[derive_deftly(HasMemoryCost)]
648pub struct SendmeTag {
649 len: NonZeroU8,
654 tag: CtByteArray<20>,
660}
661impl From<[u8; 20]> for SendmeTag {
662 #[inline]
664 fn from(value: [u8; 20]) -> Self {
665 Self {
666 len: NonZeroU8::new(20).expect("20 was not nonzero?"),
667 tag: CtByteArray::from(value),
668 }
669 }
670}
671impl From<[u8; 16]> for SendmeTag {
672 #[inline]
674 fn from(value: [u8; 16]) -> Self {
675 let mut tag = CtByteArray::from([0; 20]);
676 tag.as_mut()[0..16].copy_from_slice(&value[..]);
677 Self {
678 len: NonZeroU8::new(16).expect("16 was not nonzero?"),
679 tag,
680 }
681 }
682}
683impl AsRef<[u8]> for SendmeTag {
684 fn as_ref(&self) -> &[u8] {
685 &self.tag.as_ref()[0..usize::from(u8::from(self.len))]
686 }
687}
688#[derive(Clone, Debug, thiserror::Error)]
690#[non_exhaustive]
691#[error("Invalid size {} on SENDME tag", len)]
692pub struct InvalidSendmeTag {
693 len: usize,
695}
696impl From<InvalidSendmeTag> for tor_bytes::Error {
697 fn from(_: InvalidSendmeTag) -> Self {
698 tor_bytes::Error::BadLengthValue
699 }
700}
701
702impl<'a> TryFrom<&'a [u8]> for SendmeTag {
703 type Error = InvalidSendmeTag;
704
705 #[inline]
707 fn try_from(value: &'a [u8]) -> std::result::Result<Self, Self::Error> {
708 match value.len() {
709 16 => {
710 let a: [u8; 16] = value.try_into().expect("16 was not 16?");
711 Ok(Self::from(a))
712 }
713 20 => {
714 let a: [u8; 20] = value.try_into().expect("20 was not 20?");
715 Ok(Self::from(a))
716 }
717 _ => Err(InvalidSendmeTag { len: value.len() }),
718 }
719 }
720}
721
722#[derive(Debug, Clone, Deftly)]
739#[derive_deftly(HasMemoryCost)]
740pub struct Sendme {
741 tag: Option<SendmeTag>,
743}
744impl Sendme {
745 pub fn new_empty() -> Self {
750 Sendme { tag: None }
751 }
752 pub fn new_tag(x: [u8; 20]) -> Self {
754 Sendme {
755 tag: Some(x.into()),
756 }
757 }
758 pub fn into_sendme_tag(self) -> Option<SendmeTag> {
760 self.tag
761 }
762}
763impl From<SendmeTag> for Sendme {
764 fn from(value: SendmeTag) -> Self {
765 Self { tag: Some(value) }
766 }
767}
768impl Body for Sendme {
769 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
770 let tag = if r.remaining() == 0 {
771 None
772 } else {
773 let ver = r.take_u8()?;
774 match ver {
775 0 => None,
776 1 => {
777 let dlen = r.take_u16()?;
778 Some(r.take(dlen as usize)?.try_into()?)
779 }
780 _ => {
781 return Err(Error::InvalidMessage("Unrecognized SENDME version.".into()));
782 }
783 }
784 };
785 Ok(Sendme { tag })
786 }
787 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
788 match self.tag {
789 None => (),
790 Some(x) => {
791 w.write_u8(1);
792 let x = x.as_ref();
793 let bodylen: u16 = x
794 .len()
795 .try_into()
796 .map_err(|_| EncodeError::BadLengthValue)?;
797 w.write_u16(bodylen);
798 w.write_all(x);
799 }
800 }
801 Ok(())
802 }
803}
804
805#[derive(Debug, Clone, Deftly)]
810#[derive_deftly(HasMemoryCost)]
811pub struct Extend {
812 addr: Ipv4Addr,
814 port: u16,
816 handshake: Vec<u8>,
818 rsaid: RsaIdentity,
820}
821impl Extend {
822 pub fn new(addr: Ipv4Addr, port: u16, handshake: Vec<u8>, rsaid: RsaIdentity) -> Self {
824 Extend {
825 addr,
826 port,
827 handshake,
828 rsaid,
829 }
830 }
831}
832impl Body for Extend {
833 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
834 let addr = r.extract()?;
835 let port = r.take_u16()?;
836 let handshake = r.take(TAP_C_HANDSHAKE_LEN)?.into();
837 let rsaid = r.extract()?;
838 Ok(Extend {
839 addr,
840 port,
841 handshake,
842 rsaid,
843 })
844 }
845 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
846 w.write(&self.addr)?;
847 w.write_u16(self.port);
848 w.write_all(&self.handshake[..]);
849 w.write(&self.rsaid)?;
850 Ok(())
851 }
852}
853
854#[derive(Debug, Clone, Deftly)]
860#[derive_deftly(HasMemoryCost)]
861pub struct Extended {
862 handshake: Vec<u8>,
864}
865impl Extended {
866 pub fn new(handshake: Vec<u8>) -> Self {
868 Extended { handshake }
869 }
870}
871impl Body for Extended {
872 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
873 let handshake = r.take(TAP_S_HANDSHAKE_LEN)?.into();
874 Ok(Extended { handshake })
875 }
876 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
877 w.write_all(&self.handshake);
878 Ok(())
879 }
880}
881
882#[derive(Debug, Clone, Deftly)]
897#[derive_deftly(HasMemoryCost)]
898pub struct Extend2 {
899 linkspec: Vec<EncodedLinkSpec>,
905 handshake_type: HandshakeType,
907 handshake: Vec<u8>,
909}
910impl Extend2 {
911 pub fn new(
913 linkspec: Vec<EncodedLinkSpec>,
914 handshake_type: HandshakeType,
915 handshake: Vec<u8>,
916 ) -> Self {
917 Extend2 {
918 linkspec,
919 handshake_type,
920 handshake,
921 }
922 }
923
924 pub fn handshake_type(&self) -> HandshakeType {
926 self.handshake_type
927 }
928
929 pub fn handshake(&self) -> &[u8] {
931 &self.handshake[..]
932 }
933}
934
935impl Body for Extend2 {
936 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
937 let n = r.take_u8()?;
938 let linkspec = r.extract_n(n as usize)?;
939 let handshake_type = r.take_u16()?.into();
940 let hlen = r.take_u16()?;
941 let handshake = r.take(hlen as usize)?.into();
942 Ok(Extend2 {
943 linkspec,
944 handshake_type,
945 handshake,
946 })
947 }
948 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
949 let n_linkspecs: u8 = self
950 .linkspec
951 .len()
952 .try_into()
953 .map_err(|_| EncodeError::BadLengthValue)?;
954 w.write_u8(n_linkspecs);
955 for ls in &self.linkspec {
956 w.write(ls)?;
957 }
958 w.write_u16(self.handshake_type.into());
959 let handshake_len: u16 = self
960 .handshake
961 .len()
962 .try_into()
963 .map_err(|_| EncodeError::BadLengthValue)?;
964 w.write_u16(handshake_len);
965 w.write_all(&self.handshake[..]);
966 Ok(())
967 }
968}
969
970#[derive(Debug, Clone, Deftly)]
976#[derive_deftly(HasMemoryCost)]
977pub struct Extended2 {
978 handshake: Vec<u8>,
981}
982impl Extended2 {
983 pub fn new(handshake: Vec<u8>) -> Self {
985 Extended2 { handshake }
986 }
987 pub fn into_body(self) -> Vec<u8> {
989 self.handshake
990 }
991}
992impl Body for Extended2 {
993 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
994 let hlen = r.take_u16()?;
995 let handshake = r.take(hlen as usize)?;
996 Ok(Extended2 {
997 handshake: handshake.into(),
998 })
999 }
1000 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1001 let handshake_len: u16 = self
1002 .handshake
1003 .len()
1004 .try_into()
1005 .map_err(|_| EncodeError::BadLengthValue)?;
1006 w.write_u16(handshake_len);
1007 w.write_all(&self.handshake[..]);
1008 Ok(())
1009 }
1010}
1011
1012#[derive(Debug, Clone, Deftly)]
1020#[derive_deftly(HasMemoryCost)]
1021pub struct Truncated {
1022 reason: DestroyReason,
1024}
1025impl Truncated {
1026 pub fn new(reason: DestroyReason) -> Self {
1028 Truncated { reason }
1029 }
1030 pub fn reason(self) -> DestroyReason {
1032 self.reason
1033 }
1034}
1035impl Body for Truncated {
1036 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1037 Ok(Truncated {
1038 reason: r.take_u8()?.into(),
1039 })
1040 }
1041 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1042 w.write_u8(self.reason.into());
1043 Ok(())
1044 }
1045}
1046
1047#[derive(Debug, Clone, Deftly)]
1054#[derive_deftly(HasMemoryCost)]
1055pub struct Resolve {
1056 query: Vec<u8>,
1058}
1059impl Resolve {
1060 pub fn new(s: &str) -> Self {
1062 Resolve {
1063 query: s.as_bytes().into(),
1064 }
1065 }
1066 pub fn new_reverse(addr: &IpAddr) -> Self {
1068 let query = match addr {
1069 IpAddr::V4(v4) => {
1070 let [a, b, c, d] = v4.octets();
1071 format!("{}.{}.{}.{}.in-addr.arpa", d, c, b, a)
1072 }
1073 IpAddr::V6(v6) => {
1074 let mut s = String::with_capacity(72);
1075 for o in v6.octets().iter().rev() {
1076 let high_nybble = o >> 4;
1077 let low_nybble = o & 15;
1078 write!(s, "{:x}.{:x}.", low_nybble, high_nybble)
1079 .expect("write to string failed");
1080 }
1081 write!(s, "ip6.arpa").expect("write to string failed");
1082 s
1083 }
1084 };
1085 Resolve {
1086 query: query.into_bytes(),
1087 }
1088 }
1089}
1090impl Body for Resolve {
1091 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1092 let query = r.take_until(0)?;
1093 Ok(Resolve {
1094 query: query.into(),
1095 })
1096 }
1097 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1098 w.write_all(&self.query[..]);
1099 w.write_u8(0);
1100 Ok(())
1101 }
1102}
1103
1104#[derive(Debug, Clone, Eq, PartialEq, Deftly)]
1106#[derive_deftly(HasMemoryCost)]
1107#[non_exhaustive]
1108pub enum ResolvedVal {
1109 Ip(IpAddr),
1111 Hostname(Vec<u8>),
1113 TransientError,
1115 NontransientError,
1117 Unrecognized(u8, Vec<u8>),
1119}
1120
1121const RES_HOSTNAME: u8 = 0;
1123const RES_IPV4: u8 = 4;
1125const RES_IPV6: u8 = 6;
1127const RES_ERR_TRANSIENT: u8 = 0xF0;
1129const RES_ERR_NONTRANSIENT: u8 = 0xF1;
1131
1132impl Readable for ResolvedVal {
1133 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1134 fn res_len(tp: u8) -> Option<usize> {
1137 match tp {
1138 RES_IPV4 => Some(4),
1139 RES_IPV6 => Some(16),
1140 _ => None,
1141 }
1142 }
1143 let tp = r.take_u8()?;
1144 let len = r.take_u8()? as usize;
1145 if let Some(expected_len) = res_len(tp) {
1146 if len != expected_len {
1147 return Err(Error::InvalidMessage(
1148 "Wrong length for RESOLVED answer".into(),
1149 ));
1150 }
1151 }
1152 Ok(match tp {
1153 RES_HOSTNAME => Self::Hostname(r.take(len)?.into()),
1154 RES_IPV4 => Self::Ip(IpAddr::V4(r.extract()?)),
1155 RES_IPV6 => Self::Ip(IpAddr::V6(r.extract()?)),
1156 RES_ERR_TRANSIENT => {
1157 r.advance(len)?;
1158 Self::TransientError
1159 }
1160 RES_ERR_NONTRANSIENT => {
1161 r.advance(len)?;
1162 Self::NontransientError
1163 }
1164 _ => Self::Unrecognized(tp, r.take(len)?.into()),
1165 })
1166 }
1167}
1168
1169impl Writeable for ResolvedVal {
1170 fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
1171 match self {
1172 Self::Hostname(h) => {
1173 w.write_u8(RES_HOSTNAME);
1174 let h_len: u8 = h
1175 .len()
1176 .try_into()
1177 .map_err(|_| EncodeError::BadLengthValue)?;
1178 w.write_u8(h_len);
1179 w.write_all(&h[..]);
1180 }
1181 Self::Ip(IpAddr::V4(a)) => {
1182 w.write_u8(RES_IPV4);
1183 w.write_u8(4); w.write(a)?;
1185 }
1186 Self::Ip(IpAddr::V6(a)) => {
1187 w.write_u8(RES_IPV6);
1188 w.write_u8(16); w.write(a)?;
1190 }
1191 Self::TransientError => {
1192 w.write_u8(RES_ERR_TRANSIENT);
1193 w.write_u8(0); }
1195 Self::NontransientError => {
1196 w.write_u8(RES_ERR_NONTRANSIENT);
1197 w.write_u8(0); }
1199 Self::Unrecognized(tp, v) => {
1200 w.write_u8(*tp);
1201 let v_len: u8 = v
1202 .len()
1203 .try_into()
1204 .map_err(|_| EncodeError::BadLengthValue)?;
1205 w.write_u8(v_len);
1206 w.write_all(&v[..]);
1207 }
1208 }
1209 Ok(())
1210 }
1211}
1212
1213#[derive(Debug, Clone, Deftly)]
1218#[derive_deftly(HasMemoryCost)]
1219pub struct Resolved {
1220 answers: Vec<(ResolvedVal, u32)>,
1222}
1223impl Resolved {
1224 pub fn new_empty() -> Self {
1226 Resolved {
1227 answers: Vec::new(),
1228 }
1229 }
1230 pub fn new_err(transient: bool, ttl: u32) -> Self {
1235 let mut res = Self::new_empty();
1236 let err = if transient {
1237 ResolvedVal::TransientError
1238 } else {
1239 ResolvedVal::NontransientError
1240 };
1241 res.add_answer(err, ttl);
1242 res
1243 }
1244 pub fn add_answer(&mut self, answer: ResolvedVal, ttl: u32) {
1246 self.answers.push((answer, ttl));
1247 }
1248
1249 pub fn into_answers(self) -> Vec<(ResolvedVal, u32)> {
1257 self.answers
1258 }
1259}
1260impl Body for Resolved {
1261 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1262 let mut answers = Vec::new();
1263 while r.remaining() > 0 {
1264 let rv = r.extract()?;
1265 let ttl = r.take_u32()?;
1266 answers.push((rv, ttl));
1267 }
1268 Ok(Resolved { answers })
1269 }
1270 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1271 for (rv, ttl) in &self.answers {
1272 w.write(rv)?;
1273 w.write_u32(*ttl);
1274 }
1275 Ok(())
1276 }
1277}
1278
1279#[derive(Debug, Clone, Deftly)]
1283#[derive_deftly(HasMemoryCost)]
1284pub struct Unrecognized {
1285 cmd: RelayCmd,
1287 body: Vec<u8>,
1289}
1290
1291impl Unrecognized {
1292 pub fn new<B>(cmd: RelayCmd, body: B) -> Self
1294 where
1295 B: Into<Vec<u8>>,
1296 {
1297 let body = body.into();
1298 Unrecognized { cmd, body }
1299 }
1300
1301 pub fn cmd(&self) -> RelayCmd {
1303 self.cmd
1304 }
1305 pub fn decode_with_cmd(cmd: RelayCmd, r: &mut Reader<'_>) -> Result<Self> {
1307 let mut r = Unrecognized::decode_from_reader(r)?;
1308 r.cmd = cmd;
1309 Ok(r)
1310 }
1311}
1312
1313impl Body for Unrecognized {
1314 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1315 Ok(Unrecognized {
1316 cmd: 0.into(),
1317 body: r.take(r.remaining())?.into(),
1318 })
1319 }
1320 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1321 w.write_all(&self.body[..]);
1322 Ok(())
1323 }
1324}
1325
1326macro_rules! empty_body {
1328 {
1329 $(#[$meta:meta])*
1330 pub struct $name:ident {}
1331 } => {
1332 $(#[$meta])*
1333 #[derive(Clone,Debug,Default,derive_deftly::Deftly)]
1334 #[derive_deftly(tor_memquota::HasMemoryCost)]
1335 #[non_exhaustive]
1336 pub struct $name {}
1337 impl $crate::relaycell::msg::Body for $name {
1338 fn decode_from_reader(_r: &mut Reader<'_>) -> Result<Self> {
1339 Ok(Self::default())
1340 }
1341 fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
1342 Ok(())
1343 }
1344 }
1345 }
1346}
1347#[allow(unused_imports)] pub(crate) use empty_body;
1349
1350empty_body! {
1351 pub struct Drop {}
1353}
1354empty_body! {
1355 pub struct Truncate {}
1357}
1358empty_body! {
1359 pub struct BeginDir {}
1361}
1362
1363macro_rules! msg_impl_relaymsg {
1373 ($($body:ident),* $(,)?) =>
1374 {paste::paste!{
1375 $(impl crate::relaycell::RelayMsg for $body {
1376 fn cmd(&self) -> crate::relaycell::RelayCmd { crate::relaycell::RelayCmd::[< $body:snake:upper >] }
1377 fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1378 crate::relaycell::msg::Body::encode_onto(self, w)
1379 }
1380 fn decode_from_reader(cmd: RelayCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1381 if cmd != crate::relaycell::RelayCmd::[< $body:snake:upper >] {
1382 return Err(tor_bytes::Error::InvalidMessage(
1383 format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1384 ));
1385 }
1386 crate::relaycell::msg::Body::decode_from_reader(r)
1387 }
1388 }
1389
1390 impl TryFrom<AnyRelayMsg> for $body {
1391 type Error = crate::Error;
1392 fn try_from(msg: AnyRelayMsg) -> crate::Result<$body> {
1393 use crate::relaycell::RelayMsg;
1394 match msg {
1395 AnyRelayMsg::$body(b) => Ok(b),
1396 _ => Err(crate::Error::CircProto(format!("Expected {}; got {}" ,
1397 stringify!([<$body:snake:upper>]),
1398 msg.cmd())) ),
1399 }
1400 }
1401 }
1402 )*
1403 }}
1404}
1405
1406msg_impl_relaymsg!(
1407 Begin, Data, End, Connected, Sendme, Extend, Extended, Extend2, Extended2, Truncate, Truncated,
1408 Drop, Resolve, Resolved, BeginDir,
1409);
1410
1411#[cfg(feature = "experimental-udp")]
1412msg_impl_relaymsg!(ConnectUdp, ConnectedUdp, Datagram);
1413
1414#[cfg(feature = "hs")]
1415msg_impl_relaymsg!(
1416 EstablishIntro,
1417 EstablishRendezvous,
1418 Introduce1,
1419 Introduce2,
1420 Rendezvous1,
1421 Rendezvous2,
1422 IntroEstablished,
1423 RendezvousEstablished,
1424 IntroduceAck,
1425);
1426
1427#[cfg(feature = "conflux")]
1428msg_impl_relaymsg!(ConfluxSwitch, ConfluxLink, ConfluxLinked, ConfluxLinkedAck);
1429
1430msg_impl_relaymsg!(Xon, Xoff);
1431
1432#[cfg(test)]
1433mod test {
1434 #![allow(clippy::bool_assert_comparison)]
1436 #![allow(clippy::clone_on_copy)]
1437 #![allow(clippy::dbg_macro)]
1438 #![allow(clippy::mixed_attributes_style)]
1439 #![allow(clippy::print_stderr)]
1440 #![allow(clippy::print_stdout)]
1441 #![allow(clippy::single_char_pattern)]
1442 #![allow(clippy::unwrap_used)]
1443 #![allow(clippy::unchecked_time_subtraction)]
1444 #![allow(clippy::useless_vec)]
1445 #![allow(clippy::needless_pass_by_value)]
1446 use super::*;
1449
1450 #[test]
1451 fn sendme_tags() {
1452 let ts: Vec<SendmeTag> = vec![
1454 (*b"Yea, on the word of ").into(),
1455 (*b"a Bloom, ye shal").into(),
1456 (*b"l ere long enter int").into(),
1457 (*b"o the golden cit").into(),
1458 ];
1459
1460 for (i1, i2) in (0..4).zip(0..4) {
1461 if i1 == i2 {
1462 assert_eq!(ts[i1], ts[i2]);
1463 } else {
1464 assert_ne!(ts[i1], ts[i2]);
1465 }
1466 }
1467
1468 assert_eq!(ts[0].as_ref(), &b"Yea, on the word of "[..]);
1469 assert_eq!(ts[3].as_ref(), &b"o the golden cit"[..]);
1470
1471 assert_eq!(ts[1], b"a Bloom, ye shal"[..].try_into().unwrap());
1472 assert_eq!(ts[2], b"l ere long enter int"[..].try_into().unwrap());
1473
1474 assert!(matches!(
1476 SendmeTag::try_from(&b"o the golden ci"[..]),
1477 Err(InvalidSendmeTag { .. }),
1478 ));
1479 }
1480}