tor_cell/relaycell/
msg.rs

1//! Encoding and decoding for relay messages
2//!
3//! Relay messages are sent along circuits, inside RELAY or RELAY_EARLY
4//! cells.
5
6use 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/// A single parsed relay message, sent or received along a circuit
39#[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    /// Create a stream
45    Begin,
46    /// Send data on a stream
47    Data,
48    /// Close a stream
49    End,
50    /// Successful response to a Begin message
51    Connected,
52    /// For flow control
53    Sendme,
54    /// Extend a circuit to a new hop (deprecated)
55    Extend,
56    /// Successful response to an Extend message (deprecated)
57    Extended,
58    /// Extend a circuit to a new hop
59    Extend2,
60    /// Successful response to an Extend2 message
61    Extended2,
62    /// Partially close a circuit
63    Truncate,
64    /// Tell the client that a circuit has been partially closed
65    Truncated,
66    /// Used for padding
67    Drop,
68    /// Launch a DNS request
69    Resolve,
70    /// Response to a Resolve message
71    Resolved,
72    /// Start a directory stream
73    BeginDir,
74    /// Start a UDP stream.
75    [feature = "experimental-udp"]
76    ConnectUdp,
77    /// Successful response to a ConnectUdp message
78    [feature = "experimental-udp"]
79    ConnectedUdp,
80    /// UDP stream data
81    [feature = "experimental-udp"]
82    Datagram,
83    /// Link circuits together at the receiving endpoint
84    [feature = "conflux"]
85    ConfluxLink,
86    /// Confirm that the circuits were linked
87    [feature = "conflux"]
88    ConfluxLinked,
89    /// Acknowledge the linkage of the circuits, for RTT measurement.
90    [feature = "conflux"]
91    ConfluxLinkedAck,
92    /// Switch to another leg in an already linked circuit construction.
93    [feature = "conflux"]
94    ConfluxSwitch,
95    /// Establish Introduction
96    [feature = "hs"]
97    EstablishIntro,
98    /// Establish Rendezvous
99    [feature = "hs"]
100    EstablishRendezvous,
101    /// Introduce1 (client to introduction point)
102    [feature = "hs"]
103    Introduce1,
104    /// Introduce2 (introduction point to service)
105    [feature = "hs"]
106    Introduce2,
107    /// Rendezvous1 (service to rendezvous point)
108    [feature = "hs"]
109    Rendezvous1,
110    /// Rendezvous2 (rendezvous point to client)
111    [feature = "hs"]
112    Rendezvous2,
113    /// Acknowledgement for EstablishIntro.
114    [feature = "hs"]
115    IntroEstablished,
116    /// Acknowledgment for EstablishRendezvous.
117    [feature = "hs"]
118    RendezvousEstablished,
119    /// Acknowledgement for Introduce1.
120    [feature = "hs"]
121    IntroduceAck,
122
123    _ =>
124    /// An unrecognized command.
125    Unrecognized,
126    }
127}
128
129/// Internal: traits in common different cell bodies.
130pub trait Body: Sized {
131    /// Decode a relay cell body from a provided reader.
132    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self>;
133    /// Encode the body of this cell into the end of a writer.
134    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()>;
135}
136
137bitflags! {
138    /// A set of recognized flags that can be attached to a begin cell.
139    ///
140    /// For historical reasons, these flags are constructed so that 0
141    /// is a reasonable default for all of them.
142    #[derive(Clone, Copy, Debug)]
143    pub struct BeginFlags : u32 {
144        /// The client would accept a connection to an IPv6 address.
145        const IPV6_OKAY = (1<<0);
146        /// The client would not accept a connection to an IPv4 address.
147        const IPV4_NOT_OKAY = (1<<1);
148        /// The client would rather have a connection to an IPv6 address.
149        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/// A preference for IPv4 vs IPv6 addresses; usable as a nicer frontend for
160/// BeginFlags.
161#[derive(Clone, Default, Copy, Debug, Eq, PartialEq)]
162#[non_exhaustive]
163pub enum IpVersionPreference {
164    /// Only IPv4 is allowed.
165    Ipv4Only,
166    /// IPv4 and IPv6 are both allowed, and IPv4 is preferred.
167    #[default]
168    Ipv4Preferred,
169    /// IPv4 and IPv6 are both allowed, and IPv6 is preferred.
170    Ipv6Preferred,
171    /// Only IPv6 is allowed.
172    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/// A Begin message creates a new data stream.
187///
188/// Upon receiving a Begin message, relays should try to open a new stream
189/// for the client, if their exit policy permits, and associate it with a
190/// new TCP connection to the target address.
191///
192/// If the exit decides to reject the Begin message, or if the TCP
193/// connection fails, the exit should send an End message.
194///
195/// Clients should reject these messages.
196#[derive(Debug, Clone, Deftly)]
197#[derive_deftly(HasMemoryCost)]
198pub struct Begin {
199    /// Ascii string describing target address
200    addr: Vec<u8>,
201    /// Target port
202    port: u16,
203    /// Flags that describe how to resolve the address
204    flags: BeginFlags,
205}
206
207impl Begin {
208    /// Construct a new Begin cell
209    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    /// Return the address requested in this message.
226    pub fn addr(&self) -> &[u8] {
227        &self.addr[..]
228    }
229
230    /// Return the port requested by this message.
231    pub fn port(&self) -> u16 {
232        self.port
233    }
234
235    /// Return the set of flags provided in this message.
236    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                // IPv6 address
246                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                // IPv4 address, or hostname.
255                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/// A Data message represents data sent along a stream.
299///
300/// Upon receiving a Data message for a live stream, the client or
301/// exit sends that data onto the associated TCP connection.
302///
303/// These messages hold between 1 and [Data::MAXLEN] bytes of data each;
304/// they are the most numerous messages on the Tor network.
305#[derive(Debug, Clone, Deftly)]
306#[derive_deftly(HasMemoryCost)]
307pub struct Data {
308    /// Contents of the cell, to be sent on a specific stream
309    ///
310    /// INVARIANT: Holds between 1 and [`Data::MAXLEN`] bytes, inclusive.
311    //
312    // TODO: There's a good case to be made that this should be a BoxedCellBody
313    // instead, to avoid allocations and copies.  But first probably we should
314    // figure out how proposal 340 will work with this.  Possibly, we will wind
315    // up using `bytes` or something.
316    body: Vec<u8>,
317}
318impl Data {
319    /// The longest allowable body length for a single V0 data cell.
320    ///
321    /// Relay command (1) + 'Recognized' (2) + StreamID (2) + Digest (4) + Length (2) = 11
322    pub const MAXLEN_V0: usize = CELL_DATA_LEN - 11;
323
324    /// The longest allowable body length for a single V1 data cell.
325    ///
326    /// Tag (16) + Relay command (1) + Length (2) + StreamID (2) = 21
327    pub const MAXLEN_V1: usize = CELL_DATA_LEN - 21;
328
329    /// The longest allowable body length for any data cell.
330    ///
331    /// Note that this value is too large to fit into a v1 relay cell;
332    /// see [`MAXLEN_V1`](Data::MAXLEN_V1) if you are making a v1 data cell.
333    ///
334    pub const MAXLEN: usize = Data::MAXLEN_V0;
335
336    /// Construct a new data cell.
337    ///
338    /// Returns an error if `inp` is longer than [`Data::MAXLEN`] bytes.
339    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    /// Construct a new data cell, taking as many bytes from `inp`
350    /// as possible.
351    ///
352    /// Return the data cell, and a slice holding any bytes that
353    /// wouldn't fit (if any).
354    ///
355    /// Returns None if the input was empty.
356    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    /// Construct a new data cell from a provided vector of bytes.
367    ///
368    /// The vector _must_ not have more than [`Data::MAXLEN`] bytes, and must
369    /// not be empty.
370    fn new_unchecked(body: Vec<u8>) -> Self {
371        debug_assert!((1..=Data::MAXLEN).contains(&body.len()));
372        Data { body }
373    }
374
375    /// Return the maximum allowable body length for a Data message
376    /// using the provided `format`.
377    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/// An End message tells the other end of the circuit to close a stream.
411///
412/// Note that End messages do not implement a true half-closed state,
413/// so after sending an End message each party needs to wait a while
414/// to be sure that the stream is completely dead.
415#[derive(Debug, Clone, Deftly)]
416#[derive_deftly(HasMemoryCost)]
417pub struct End {
418    /// Reason for closing the stream
419    reason: EndReason,
420    /// If the reason is EXITPOLICY, this holds the resolved address an
421    /// associated TTL.  The TTL is set to MAX if none was given.
422    addr: Option<(IpAddr, u32)>,
423}
424
425caret_int! {
426    /// A declared reason for closing a stream
427    #[derive(Deftly)]
428    #[derive_deftly(HasMemoryCost)]
429    pub struct EndReason(u8) {
430        /// Closing a stream because of an unspecified reason.
431        ///
432        /// This is the only END reason that clients send.
433        MISC = 1,
434        /// Couldn't look up hostname.
435        RESOLVEFAILED = 2,
436        /// Remote host refused connection.
437        CONNECTREFUSED = 3,
438        /// Closing a stream because of an exit-policy violation.
439        EXITPOLICY = 4,
440        /// Circuit destroyed
441        DESTROY = 5,
442        /// Anonymized TCP connection was closed
443        DONE = 6,
444        /// Connection timed out, or OR timed out while connecting
445        TIMEOUT = 7,
446        /// No route to target destination.
447        NOROUTE = 8,
448        /// OR is entering hibernation and not handling requests
449        HIBERNATING = 9,
450        /// Internal error at the OR
451        INTERNAL = 10,
452        /// Ran out of resources to fulfill requests
453        RESOURCELIMIT = 11,
454        /// Connection unexpectedly reset
455        CONNRESET = 12,
456        /// Tor protocol violation
457        TORPROTOCOL = 13,
458        /// BEGIN_DIR cell at a non-directory-cache.
459        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    /// Make a new END_REASON_MISC message.
486    ///
487    /// Clients send this every time they decide to close a stream.
488    pub fn new_misc() -> Self {
489        End {
490            reason: EndReason::MISC,
491            addr: None,
492        }
493    }
494    /// Make a new END message with the provided end reason.
495    pub fn new_with_reason(reason: EndReason) -> Self {
496        End { reason, addr: None }
497    }
498    /// Make a new END message with END_REASON_EXITPOLICY, and the
499    /// provided address and ttl.
500    pub fn new_exitpolicy(addr: IpAddr, ttl: u32) -> Self {
501        End {
502            reason: EndReason::EXITPOLICY,
503            addr: Some((addr, ttl)),
504        }
505    }
506    /// Return the provided EndReason for this End cell.
507    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                    // Ignores other message lengths.
526                    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/// A Connected message is a successful response to a Begin message
577///
578/// When an outgoing connection succeeds, the exit sends a Connected
579/// back to the client.
580///
581/// Clients never send Connected messages.
582#[derive(Debug, Clone, Deftly)]
583#[derive_deftly(HasMemoryCost)]
584pub struct Connected {
585    /// Resolved address and TTL (time to live) in seconds
586    addr: Option<(IpAddr, u32)>,
587}
588impl Connected {
589    /// Construct a new empty connected cell.
590    pub fn new_empty() -> Self {
591        Connected { addr: None }
592    }
593    /// Construct a connected cell with an address and a time-to-live value.
594    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/// A Sendme message is used to increase flow-control windows.
639///
640/// To avoid congestion, each Tor circuit and stream keeps track of a
641/// number of data cells that it is willing to send.  It decrements
642/// these numbers every time it sends a cell.  If these numbers reach
643/// zero, then no more cells can be sent on the stream or circuit.
644///
645/// The only way to re-increment these numbers is by receiving a
646/// Sendme cell from the other end of the circuit or stream.
647///
648/// For security, current circuit-level Sendme cells include an
649/// authentication tag that proves knowledge of the cells that they are
650/// acking.
651///
652/// See [tor-spec.txt](https://spec.torproject.org/tor-spec) for more
653/// information; also see the source for `tor_proto::circuit::sendme`.
654#[derive(Debug, Clone, Deftly)]
655#[derive_deftly(HasMemoryCost)]
656pub struct Sendme {
657    /// A tag value authenticating the previously received data.
658    digest: Option<Vec<u8>>,
659}
660impl Sendme {
661    /// Return a new empty sendme cell
662    ///
663    /// This format is used on streams, and on circuits without sendme
664    /// authentication.
665    pub fn new_empty() -> Self {
666        Sendme { digest: None }
667    }
668    /// This format is used on circuits with sendme authentication.
669    pub fn new_tag(x: [u8; 20]) -> Self {
670        Sendme {
671            digest: Some(x.into()),
672        }
673    }
674    /// Consume this cell and return its authentication tag, if any
675    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/// Extend was an obsolete circuit extension message format.
716///
717/// This format only handled IPv4 addresses, RSA identities, and the
718/// TAP handshake.  Modern Tor clients use Extend2 instead.
719#[derive(Debug, Clone, Deftly)]
720#[derive_deftly(HasMemoryCost)]
721pub struct Extend {
722    /// Where to extend to (address)
723    addr: Ipv4Addr,
724    /// Where to extend to (port)
725    port: u16,
726    /// A TAP handshake to send
727    handshake: Vec<u8>,
728    /// The RSA identity of the target relay
729    rsaid: RsaIdentity,
730}
731impl Extend {
732    /// Construct a new (deprecated) extend cell
733    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/// Extended was an obsolete circuit extension message, sent in reply to
765/// an Extend message.
766///
767/// Like Extend, the Extended message was only designed for the TAP
768/// handshake.
769#[derive(Debug, Clone, Deftly)]
770#[derive_deftly(HasMemoryCost)]
771pub struct Extended {
772    /// Contents of the handshake sent in response to the EXTEND
773    handshake: Vec<u8>,
774}
775impl Extended {
776    /// Construct a new Extended message with the provided handshake
777    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/// An Extend2 message tells the last relay in a circuit to extend to a new
793/// hop.
794///
795/// When a relay (call it R) receives an Extend2 message, it tries to
796/// find (or make) a channel to the other relay (R') described in the
797/// list of link specifiers. (A link specifier can be an IP addresses
798/// or a cryptographic identity).  Once R has such a channel, the
799/// it packages the client's handshake data as a new Create2 message
800/// R'.  If R' replies with a Created2 (success) message, R packages
801/// that message's contents in an Extended message.
802//
803/// Unlike Extend messages, Extend2 messages can encode any handshake
804/// type, and can describe relays in ways other than IPv4 addresses
805/// and RSA identities.
806#[derive(Debug, Clone, Deftly)]
807#[derive_deftly(HasMemoryCost)]
808pub struct Extend2 {
809    /// A vector of "link specifiers"
810    ///
811    /// These link specifiers describe where to find the target relay
812    /// that the recipient should extend to.  They include things like
813    /// IP addresses and identity keys.
814    linkspec: Vec<EncodedLinkSpec>,
815    /// Type of handshake to be sent in a CREATE2 cell
816    handshake_type: HandshakeType,
817    /// Body of the handshake to be sent in a CREATE2 cell
818    handshake: Vec<u8>,
819}
820impl Extend2 {
821    /// Create a new Extend2 cell.
822    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    /// Return the type of this handshake.
835    pub fn handshake_type(&self) -> HandshakeType {
836        self.handshake_type
837    }
838
839    /// Return the inner handshake for this Extend2 cell.
840    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/// Extended2 is a successful reply to an Extend2 message.
881///
882/// Extended2 messages are generated by the former last hop of a
883/// circuit, to tell the client that they have successfully completed
884/// a handshake on the client's behalf.
885#[derive(Debug, Clone, Deftly)]
886#[derive_deftly(HasMemoryCost)]
887pub struct Extended2 {
888    /// Contents of the CREATED2 cell that the new final hop sent in
889    /// response
890    handshake: Vec<u8>,
891}
892impl Extended2 {
893    /// Construct a new Extended2 message with the provided handshake
894    pub fn new(handshake: Vec<u8>) -> Self {
895        Extended2 { handshake }
896    }
897    /// Consume this extended2 cell and return its body.
898    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/// A Truncated message is sent to the client when the remaining hops
923/// of a circuit have gone away.
924///
925/// NOTE: Current Tor implementations often treat Truncated messages and
926/// Destroy messages interchangeably.  Truncated was intended to be a
927/// "soft" Destroy, that would leave the unaffected parts of a circuit
928/// still usable.
929#[derive(Debug, Clone, Deftly)]
930#[derive_deftly(HasMemoryCost)]
931pub struct Truncated {
932    /// Reason for which this circuit was truncated.
933    reason: DestroyReason,
934}
935impl Truncated {
936    /// Construct a new truncated message.
937    pub fn new(reason: DestroyReason) -> Self {
938        Truncated { reason }
939    }
940    /// Get the provided reason to truncate the circuit.
941    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/// A Resolve message launches a DNS lookup stream.
958///
959/// A client sends a Resolve message when it wants to perform a DNS
960/// lookup _without_ connecting to the resulting address.  On success
961/// the exit responds with a Resolved message; on failure it responds
962/// with an End message.
963#[derive(Debug, Clone, Deftly)]
964#[derive_deftly(HasMemoryCost)]
965pub struct Resolve {
966    /// Ascii-encoded address to resolve
967    query: Vec<u8>,
968}
969impl Resolve {
970    /// Construct a new resolve message to look up a hostname.
971    pub fn new(s: &str) -> Self {
972        Resolve {
973            query: s.as_bytes().into(),
974        }
975    }
976    /// Construct a new resolve message to do a reverse lookup on an address
977    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/// Possible response to a DNS lookup
1014#[derive(Debug, Clone, Eq, PartialEq, Deftly)]
1015#[derive_deftly(HasMemoryCost)]
1016#[non_exhaustive]
1017pub enum ResolvedVal {
1018    /// We found an IP address
1019    Ip(IpAddr),
1020    /// We found a hostname
1021    Hostname(Vec<u8>),
1022    /// Error; try again
1023    TransientError,
1024    /// Error; don't try again
1025    NontransientError,
1026    /// A DNS lookup response that we didn't recognize
1027    Unrecognized(u8, Vec<u8>),
1028}
1029
1030/// Indicates a hostname response
1031const RES_HOSTNAME: u8 = 0;
1032/// Indicates an IPv4 response
1033const RES_IPV4: u8 = 4;
1034/// Indicates an IPv6 response
1035const RES_IPV6: u8 = 6;
1036/// Transient error (okay to try again)
1037const RES_ERR_TRANSIENT: u8 = 0xF0;
1038/// Non-transient error (don't try again)
1039const RES_ERR_NONTRANSIENT: u8 = 0xF1;
1040
1041impl Readable for ResolvedVal {
1042    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1043        /// Helper: return the expected length of a resolved answer with
1044        /// a given type, if there is a particular expected length.
1045        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); // length
1093                w.write(a)?;
1094            }
1095            Self::Ip(IpAddr::V6(a)) => {
1096                w.write_u8(RES_IPV6);
1097                w.write_u8(16); // length
1098                w.write(a)?;
1099            }
1100            Self::TransientError => {
1101                w.write_u8(RES_ERR_TRANSIENT);
1102                w.write_u8(0); // length
1103            }
1104            Self::NontransientError => {
1105                w.write_u8(RES_ERR_NONTRANSIENT);
1106                w.write_u8(0); // length
1107            }
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/// A Resolved message is a successful reply to a Resolve message.
1123///
1124/// The Resolved message contains a list of zero or more addresses,
1125/// and their associated times-to-live in seconds.
1126#[derive(Debug, Clone, Deftly)]
1127#[derive_deftly(HasMemoryCost)]
1128pub struct Resolved {
1129    /// List of addresses and their associated time-to-live values.
1130    answers: Vec<(ResolvedVal, u32)>,
1131}
1132impl Resolved {
1133    /// Return a new empty Resolved object with no answers.
1134    pub fn new_empty() -> Self {
1135        Resolved {
1136            answers: Vec::new(),
1137        }
1138    }
1139    /// Return a new Resolved object reporting a name lookup error.
1140    ///
1141    /// TODO: Is getting no answer an error; or it is represented by
1142    /// a list of no answers?
1143    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    /// Add a single answer to this Resolved message
1154    pub fn add_answer(&mut self, answer: ResolvedVal, ttl: u32) {
1155        self.answers.push((answer, ttl));
1156    }
1157
1158    /// Consume this Resolved message, returning a vector of the
1159    /// answers and TTL values that it contains.
1160    ///
1161    /// Note that actually relying on these TTL values can be
1162    /// dangerous in practice, since the relay that sent the cell
1163    /// could be lying in order to cause more lookups, or to get a
1164    /// false answer cached for longer.
1165    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/// A relay message that we didn't recognize
1189///
1190/// NOTE: Clients should generally reject these.
1191#[derive(Debug, Clone, Deftly)]
1192#[derive_deftly(HasMemoryCost)]
1193pub struct Unrecognized {
1194    /// Command that we didn't recognize
1195    cmd: RelayCmd,
1196    /// Body associated with that command
1197    body: Vec<u8>,
1198}
1199
1200impl Unrecognized {
1201    /// Create a new 'unrecognized' cell.
1202    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    /// Return the command associated with this message
1211    pub fn cmd(&self) -> RelayCmd {
1212        self.cmd
1213    }
1214    /// Decode this message, using a provided command.
1215    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
1235/// Declare a message type for a message with an empty body.
1236macro_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    /// A padding message, which is always ignored.
1260    pub struct Drop {}
1261}
1262empty_body! {
1263    /// Tells a circuit to close all downstream hops on the circuit.
1264    pub struct Truncate {}
1265}
1266empty_body! {
1267    /// Opens a new stream on a directory cache.
1268    pub struct BeginDir {}
1269}
1270
1271/// Helper: declare a RelayMsg implementation for a message type that has a
1272/// fixed command.
1273//
1274// TODO: It might be better to merge Body with RelayMsg, but that is complex,
1275// since their needs are _slightly_ different.
1276//
1277// TODO: If we *do* make the change above, then perhaps we should also implement
1278// our restricted enums in terms of this, so that there is only one instance of
1279// [<$body:snake:upper>]
1280macro_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);