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::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 data cell.
320    /// Relay command (1) + 'Recognized' (2) + StreamID (2) + Digest (4) + Length (2) = 11
321    pub const MAXLEN: usize = CELL_DATA_LEN - 11;
322
323    /// Construct a new data cell.
324    ///
325    /// Returns an error if `inp` is longer than [`Data::MAXLEN`] bytes.
326    pub fn new(inp: &[u8]) -> crate::Result<Self> {
327        if inp.len() > Data::MAXLEN {
328            return Err(crate::Error::CantEncode("Data message too long"));
329        }
330        if inp.is_empty() {
331            return Err(crate::Error::CantEncode("Empty data message"));
332        }
333        Ok(Self::new_unchecked(inp.into()))
334    }
335
336    /// Construct a new data cell, taking as many bytes from `inp`
337    /// as possible.
338    ///
339    /// Return the data cell, and a slice holding any bytes that
340    /// wouldn't fit (if any).
341    ///
342    /// # Panics
343    ///
344    /// Panics if `inp` is empty.
345    #[deprecated(since = "0.16.1", note = "Use try_split_from instead.")]
346    pub fn split_from(inp: &[u8]) -> (Self, &[u8]) {
347        Self::try_split_from(inp).expect("Tried to split a Data message from an empty input.")
348    }
349
350    /// Construct a new data cell, taking as many bytes from `inp`
351    /// as possible.
352    ///
353    /// Return the data cell, and a slice holding any bytes that
354    /// wouldn't fit (if any).
355    ///
356    /// Returns None if the input was empty.
357    pub fn try_split_from(inp: &[u8]) -> Option<(Self, &[u8])> {
358        if inp.is_empty() {
359            return None;
360        }
361        let len = std::cmp::min(inp.len(), Data::MAXLEN);
362        let (data, remainder) = inp.split_at(len);
363        Some((Self::new_unchecked(data.into()), remainder))
364    }
365
366    /// 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}
375impl From<Data> for Vec<u8> {
376    fn from(data: Data) -> Vec<u8> {
377        data.body
378    }
379}
380impl AsRef<[u8]> for Data {
381    fn as_ref(&self) -> &[u8] {
382        &self.body[..]
383    }
384}
385
386impl Body for Data {
387    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
388        if r.remaining() == 0 {
389            return Err(Error::InvalidMessage("Empty DATA message".into()));
390        }
391        Ok(Data {
392            body: r.take(r.remaining())?.into(),
393        })
394    }
395    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
396        w.write_all(&self.body);
397        Ok(())
398    }
399}
400
401/// An End message tells the other end of the circuit to close a stream.
402///
403/// Note that End messages do not implement a true half-closed state,
404/// so after sending an End message each party needs to wait a while
405/// to be sure that the stream is completely dead.
406#[derive(Debug, Clone, Deftly)]
407#[derive_deftly(HasMemoryCost)]
408pub struct End {
409    /// Reason for closing the stream
410    reason: EndReason,
411    /// If the reason is EXITPOLICY, this holds the resolved address an
412    /// associated TTL.  The TTL is set to MAX if none was given.
413    addr: Option<(IpAddr, u32)>,
414}
415
416caret_int! {
417    /// A declared reason for closing a stream
418    #[derive(Deftly)]
419    #[derive_deftly(HasMemoryCost)]
420    pub struct EndReason(u8) {
421        /// Closing a stream because of an unspecified reason.
422        ///
423        /// This is the only END reason that clients send.
424        MISC = 1,
425        /// Couldn't look up hostname.
426        RESOLVEFAILED = 2,
427        /// Remote host refused connection.
428        CONNECTREFUSED = 3,
429        /// Closing a stream because of an exit-policy violation.
430        EXITPOLICY = 4,
431        /// Circuit destroyed
432        DESTROY = 5,
433        /// Anonymized TCP connection was closed
434        DONE = 6,
435        /// Connection timed out, or OR timed out while connecting
436        TIMEOUT = 7,
437        /// No route to target destination.
438        NOROUTE = 8,
439        /// OR is entering hibernation and not handling requests
440        HIBERNATING = 9,
441        /// Internal error at the OR
442        INTERNAL = 10,
443        /// Ran out of resources to fulfill requests
444        RESOURCELIMIT = 11,
445        /// Connection unexpectedly reset
446        CONNRESET = 12,
447        /// Tor protocol violation
448        TORPROTOCOL = 13,
449        /// BEGIN_DIR cell at a non-directory-cache.
450        NOTDIRECTORY = 14,
451    }
452}
453
454impl tor_error::HasKind for EndReason {
455    fn kind(&self) -> tor_error::ErrorKind {
456        use tor_error::ErrorKind as EK;
457        use EndReason as E;
458        match *self {
459            E::MISC => EK::RemoteStreamError,
460            E::RESOLVEFAILED => EK::RemoteHostResolutionFailed,
461            E::CONNECTREFUSED => EK::RemoteConnectionRefused,
462            E::EXITPOLICY => EK::ExitPolicyRejected,
463            E::DESTROY => EK::CircuitCollapse,
464            E::DONE => EK::RemoteStreamClosed,
465            E::TIMEOUT => EK::ExitTimeout,
466            E::NOROUTE => EK::RemoteNetworkFailed,
467            E::RESOURCELIMIT | E::HIBERNATING => EK::RelayTooBusy,
468            E::INTERNAL | E::TORPROTOCOL | E::NOTDIRECTORY => EK::TorProtocolViolation,
469            E::CONNRESET => EK::RemoteStreamReset,
470            _ => EK::RemoteStreamError,
471        }
472    }
473}
474
475impl End {
476    /// Make a new END_REASON_MISC message.
477    ///
478    /// Clients send this every time they decide to close a stream.
479    pub fn new_misc() -> Self {
480        End {
481            reason: EndReason::MISC,
482            addr: None,
483        }
484    }
485    /// Make a new END message with the provided end reason.
486    pub fn new_with_reason(reason: EndReason) -> Self {
487        End { reason, addr: None }
488    }
489    /// Make a new END message with END_REASON_EXITPOLICY, and the
490    /// provided address and ttl.
491    pub fn new_exitpolicy(addr: IpAddr, ttl: u32) -> Self {
492        End {
493            reason: EndReason::EXITPOLICY,
494            addr: Some((addr, ttl)),
495        }
496    }
497    /// Return the provided EndReason for this End cell.
498    pub fn reason(&self) -> EndReason {
499        self.reason
500    }
501}
502impl Body for End {
503    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
504        if r.remaining() == 0 {
505            return Ok(End {
506                reason: EndReason::MISC,
507                addr: None,
508            });
509        }
510        let reason = r.take_u8()?.into();
511        if reason == EndReason::EXITPOLICY {
512            let addr = match r.remaining() {
513                4 | 8 => IpAddr::V4(r.extract()?),
514                16 | 20 => IpAddr::V6(r.extract()?),
515                _ => {
516                    // Ignores other message lengths.
517                    return Ok(End { reason, addr: None });
518                }
519            };
520            let ttl = if r.remaining() == 4 {
521                r.take_u32()?
522            } else {
523                u32::MAX
524            };
525            Ok(End {
526                reason,
527                addr: Some((addr, ttl)),
528            })
529        } else {
530            Ok(End { reason, addr: None })
531        }
532    }
533    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
534        w.write_u8(self.reason.into());
535        if let (EndReason::EXITPOLICY, Some((addr, ttl))) = (self.reason, self.addr) {
536            match addr {
537                IpAddr::V4(v4) => w.write(&v4)?,
538                IpAddr::V6(v6) => w.write(&v6)?,
539            }
540            w.write_u32(ttl);
541        }
542        Ok(())
543    }
544}
545
546impl From<EndReason> for std::io::ErrorKind {
547    fn from(e: EndReason) -> Self {
548        use std::io::ErrorKind::*;
549        match e {
550            EndReason::RESOLVEFAILED => NotFound,
551            EndReason::CONNECTREFUSED => ConnectionRefused,
552            EndReason::EXITPOLICY => ConnectionRefused,
553            EndReason::DESTROY => ConnectionAborted,
554            EndReason::DONE => UnexpectedEof,
555            EndReason::TIMEOUT => TimedOut,
556            EndReason::HIBERNATING => ConnectionRefused,
557            EndReason::RESOURCELIMIT => ConnectionRefused,
558            EndReason::CONNRESET => ConnectionReset,
559            EndReason::TORPROTOCOL => InvalidData,
560            EndReason::NOTDIRECTORY => ConnectionRefused,
561            EndReason::INTERNAL | EndReason::NOROUTE | EndReason::MISC => Other,
562            _ => Other,
563        }
564    }
565}
566
567/// A Connected message is a successful response to a Begin message
568///
569/// When an outgoing connection succeeds, the exit sends a Connected
570/// back to the client.
571///
572/// Clients never send Connected messages.
573#[derive(Debug, Clone, Deftly)]
574#[derive_deftly(HasMemoryCost)]
575pub struct Connected {
576    /// Resolved address and TTL (time to live) in seconds
577    addr: Option<(IpAddr, u32)>,
578}
579impl Connected {
580    /// Construct a new empty connected cell.
581    pub fn new_empty() -> Self {
582        Connected { addr: None }
583    }
584    /// Construct a connected cell with an address and a time-to-live value.
585    pub fn new_with_addr(addr: IpAddr, ttl: u32) -> Self {
586        Connected {
587            addr: Some((addr, ttl)),
588        }
589    }
590}
591impl Body for Connected {
592    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
593        if r.remaining() == 0 {
594            return Ok(Connected { addr: None });
595        }
596        let ipv4 = r.take_u32()?;
597        let addr = if ipv4 == 0 {
598            if r.take_u8()? != 6 {
599                return Err(Error::InvalidMessage(
600                    "Invalid address type in CONNECTED cell".into(),
601                ));
602            }
603            IpAddr::V6(r.extract()?)
604        } else {
605            IpAddr::V4(ipv4.into())
606        };
607        let ttl = r.take_u32()?;
608
609        Ok(Connected {
610            addr: Some((addr, ttl)),
611        })
612    }
613    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
614        if let Some((addr, ttl)) = self.addr {
615            match addr {
616                IpAddr::V4(v4) => w.write(&v4)?,
617                IpAddr::V6(v6) => {
618                    w.write_u32(0);
619                    w.write_u8(6);
620                    w.write(&v6)?;
621                }
622            }
623            w.write_u32(ttl);
624        }
625        Ok(())
626    }
627}
628
629/// A Sendme message is used to increase flow-control windows.
630///
631/// To avoid congestion, each Tor circuit and stream keeps track of a
632/// number of data cells that it is willing to send.  It decrements
633/// these numbers every time it sends a cell.  If these numbers reach
634/// zero, then no more cells can be sent on the stream or circuit.
635///
636/// The only way to re-increment these numbers is by receiving a
637/// Sendme cell from the other end of the circuit or stream.
638///
639/// For security, current circuit-level Sendme cells include an
640/// authentication tag that proves knowledge of the cells that they are
641/// acking.
642///
643/// See [tor-spec.txt](https://spec.torproject.org/tor-spec) for more
644/// information; also see the source for `tor_proto::circuit::sendme`.
645#[derive(Debug, Clone, Deftly)]
646#[derive_deftly(HasMemoryCost)]
647pub struct Sendme {
648    /// A tag value authenticating the previously received data.
649    digest: Option<Vec<u8>>,
650}
651impl Sendme {
652    /// Return a new empty sendme cell
653    ///
654    /// This format is used on streams, and on circuits without sendme
655    /// authentication.
656    pub fn new_empty() -> Self {
657        Sendme { digest: None }
658    }
659    /// This format is used on circuits with sendme authentication.
660    pub fn new_tag(x: [u8; 20]) -> Self {
661        Sendme {
662            digest: Some(x.into()),
663        }
664    }
665    /// Consume this cell and return its authentication tag, if any
666    pub fn into_tag(self) -> Option<Vec<u8>> {
667        self.digest
668    }
669}
670impl Body for Sendme {
671    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
672        let digest = if r.remaining() == 0 {
673            None
674        } else {
675            let ver = r.take_u8()?;
676            match ver {
677                0 => None,
678                1 => {
679                    let dlen = r.take_u16()?;
680                    Some(r.take(dlen as usize)?.into())
681                }
682                _ => {
683                    return Err(Error::InvalidMessage("Unrecognized SENDME version.".into()));
684                }
685            }
686        };
687        Ok(Sendme { digest })
688    }
689    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
690        match self.digest {
691            None => (),
692            Some(x) => {
693                w.write_u8(1);
694                let bodylen: u16 = x
695                    .len()
696                    .try_into()
697                    .map_err(|_| EncodeError::BadLengthValue)?;
698                w.write_u16(bodylen);
699                w.write_all(&x);
700            }
701        }
702        Ok(())
703    }
704}
705
706/// Extend was an obsolete circuit extension message format.
707///
708/// This format only handled IPv4 addresses, RSA identities, and the
709/// TAP handshake.  Modern Tor clients use Extend2 instead.
710#[derive(Debug, Clone, Deftly)]
711#[derive_deftly(HasMemoryCost)]
712pub struct Extend {
713    /// Where to extend to (address)
714    addr: Ipv4Addr,
715    /// Where to extend to (port)
716    port: u16,
717    /// A TAP handshake to send
718    handshake: Vec<u8>,
719    /// The RSA identity of the target relay
720    rsaid: RsaIdentity,
721}
722impl Extend {
723    /// Construct a new (deprecated) extend cell
724    pub fn new(addr: Ipv4Addr, port: u16, handshake: Vec<u8>, rsaid: RsaIdentity) -> Self {
725        Extend {
726            addr,
727            port,
728            handshake,
729            rsaid,
730        }
731    }
732}
733impl Body for Extend {
734    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
735        let addr = r.extract()?;
736        let port = r.take_u16()?;
737        let handshake = r.take(TAP_C_HANDSHAKE_LEN)?.into();
738        let rsaid = r.extract()?;
739        Ok(Extend {
740            addr,
741            port,
742            handshake,
743            rsaid,
744        })
745    }
746    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
747        w.write(&self.addr)?;
748        w.write_u16(self.port);
749        w.write_all(&self.handshake[..]);
750        w.write(&self.rsaid)?;
751        Ok(())
752    }
753}
754
755/// Extended was an obsolete circuit extension message, sent in reply to
756/// an Extend message.
757///
758/// Like Extend, the Extended message was only designed for the TAP
759/// handshake.
760#[derive(Debug, Clone, Deftly)]
761#[derive_deftly(HasMemoryCost)]
762pub struct Extended {
763    /// Contents of the handshake sent in response to the EXTEND
764    handshake: Vec<u8>,
765}
766impl Extended {
767    /// Construct a new Extended message with the provided handshake
768    pub fn new(handshake: Vec<u8>) -> Self {
769        Extended { handshake }
770    }
771}
772impl Body for Extended {
773    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
774        let handshake = r.take(TAP_S_HANDSHAKE_LEN)?.into();
775        Ok(Extended { handshake })
776    }
777    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
778        w.write_all(&self.handshake);
779        Ok(())
780    }
781}
782
783/// An Extend2 message tells the last relay in a circuit to extend to a new
784/// hop.
785///
786/// When a relay (call it R) receives an Extend2 message, it tries to
787/// find (or make) a channel to the other relay (R') described in the
788/// list of link specifiers. (A link specifier can be an IP addresses
789/// or a cryptographic identity).  Once R has such a channel, the
790/// it packages the client's handshake data as a new Create2 message
791/// R'.  If R' replies with a Created2 (success) message, R packages
792/// that message's contents in an Extended message.
793//
794/// Unlike Extend messages, Extend2 messages can encode any handshake
795/// type, and can describe relays in ways other than IPv4 addresses
796/// and RSA identities.
797#[derive(Debug, Clone, Deftly)]
798#[derive_deftly(HasMemoryCost)]
799pub struct Extend2 {
800    /// A vector of "link specifiers"
801    ///
802    /// These link specifiers describe where to find the target relay
803    /// that the recipient should extend to.  They include things like
804    /// IP addresses and identity keys.
805    linkspec: Vec<EncodedLinkSpec>,
806    /// Type of handshake to be sent in a CREATE2 cell
807    handshake_type: HandshakeType,
808    /// Body of the handshake to be sent in a CREATE2 cell
809    handshake: Vec<u8>,
810}
811impl Extend2 {
812    /// Create a new Extend2 cell.
813    pub fn new(
814        linkspec: Vec<EncodedLinkSpec>,
815        handshake_type: HandshakeType,
816        handshake: Vec<u8>,
817    ) -> Self {
818        Extend2 {
819            linkspec,
820            handshake_type,
821            handshake,
822        }
823    }
824
825    /// Return the type of this handshake.
826    pub fn handshake_type(&self) -> HandshakeType {
827        self.handshake_type
828    }
829
830    /// Return the inner handshake for this Extend2 cell.
831    pub fn handshake(&self) -> &[u8] {
832        &self.handshake[..]
833    }
834}
835
836impl Body for Extend2 {
837    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
838        let n = r.take_u8()?;
839        let linkspec = r.extract_n(n as usize)?;
840        let handshake_type = r.take_u16()?.into();
841        let hlen = r.take_u16()?;
842        let handshake = r.take(hlen as usize)?.into();
843        Ok(Extend2 {
844            linkspec,
845            handshake_type,
846            handshake,
847        })
848    }
849    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
850        let n_linkspecs: u8 = self
851            .linkspec
852            .len()
853            .try_into()
854            .map_err(|_| EncodeError::BadLengthValue)?;
855        w.write_u8(n_linkspecs);
856        for ls in &self.linkspec {
857            w.write(ls)?;
858        }
859        w.write_u16(self.handshake_type.into());
860        let handshake_len: u16 = self
861            .handshake
862            .len()
863            .try_into()
864            .map_err(|_| EncodeError::BadLengthValue)?;
865        w.write_u16(handshake_len);
866        w.write_all(&self.handshake[..]);
867        Ok(())
868    }
869}
870
871/// Extended2 is a successful reply to an Extend2 message.
872///
873/// Extended2 messages are generated by the former last hop of a
874/// circuit, to tell the client that they have successfully completed
875/// a handshake on the client's behalf.
876#[derive(Debug, Clone, Deftly)]
877#[derive_deftly(HasMemoryCost)]
878pub struct Extended2 {
879    /// Contents of the CREATED2 cell that the new final hop sent in
880    /// response
881    handshake: Vec<u8>,
882}
883impl Extended2 {
884    /// Construct a new Extended2 message with the provided handshake
885    pub fn new(handshake: Vec<u8>) -> Self {
886        Extended2 { handshake }
887    }
888    /// Consume this extended2 cell and return its body.
889    pub fn into_body(self) -> Vec<u8> {
890        self.handshake
891    }
892}
893impl Body for Extended2 {
894    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
895        let hlen = r.take_u16()?;
896        let handshake = r.take(hlen as usize)?;
897        Ok(Extended2 {
898            handshake: handshake.into(),
899        })
900    }
901    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
902        let handshake_len: u16 = self
903            .handshake
904            .len()
905            .try_into()
906            .map_err(|_| EncodeError::BadLengthValue)?;
907        w.write_u16(handshake_len);
908        w.write_all(&self.handshake[..]);
909        Ok(())
910    }
911}
912
913/// A Truncated message is sent to the client when the remaining hops
914/// of a circuit have gone away.
915///
916/// NOTE: Current Tor implementations often treat Truncated messages and
917/// Destroy messages interchangeably.  Truncated was intended to be a
918/// "soft" Destroy, that would leave the unaffected parts of a circuit
919/// still usable.
920#[derive(Debug, Clone, Deftly)]
921#[derive_deftly(HasMemoryCost)]
922pub struct Truncated {
923    /// Reason for which this circuit was truncated.
924    reason: DestroyReason,
925}
926impl Truncated {
927    /// Construct a new truncated message.
928    pub fn new(reason: DestroyReason) -> Self {
929        Truncated { reason }
930    }
931    /// Get the provided reason to truncate the circuit.
932    pub fn reason(self) -> DestroyReason {
933        self.reason
934    }
935}
936impl Body for Truncated {
937    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
938        Ok(Truncated {
939            reason: r.take_u8()?.into(),
940        })
941    }
942    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
943        w.write_u8(self.reason.into());
944        Ok(())
945    }
946}
947
948/// A Resolve message launches a DNS lookup stream.
949///
950/// A client sends a Resolve message when it wants to perform a DNS
951/// lookup _without_ connecting to the resulting address.  On success
952/// the exit responds with a Resolved message; on failure it responds
953/// with an End message.
954#[derive(Debug, Clone, Deftly)]
955#[derive_deftly(HasMemoryCost)]
956pub struct Resolve {
957    /// Ascii-encoded address to resolve
958    query: Vec<u8>,
959}
960impl Resolve {
961    /// Construct a new resolve message to look up a hostname.
962    pub fn new(s: &str) -> Self {
963        Resolve {
964            query: s.as_bytes().into(),
965        }
966    }
967    /// Construct a new resolve message to do a reverse lookup on an address
968    pub fn new_reverse(addr: &IpAddr) -> Self {
969        let query = match addr {
970            IpAddr::V4(v4) => {
971                let [a, b, c, d] = v4.octets();
972                format!("{}.{}.{}.{}.in-addr.arpa", d, c, b, a)
973            }
974            IpAddr::V6(v6) => {
975                let mut s = String::with_capacity(72);
976                for o in v6.octets().iter().rev() {
977                    let high_nybble = o >> 4;
978                    let low_nybble = o & 15;
979                    write!(s, "{:x}.{:x}.", low_nybble, high_nybble).unwrap();
980                }
981                write!(s, "ip6.arpa").unwrap();
982                s
983            }
984        };
985        Resolve {
986            query: query.into_bytes(),
987        }
988    }
989}
990impl Body for Resolve {
991    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
992        let query = r.take_until(0)?;
993        Ok(Resolve {
994            query: query.into(),
995        })
996    }
997    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
998        w.write_all(&self.query[..]);
999        w.write_u8(0);
1000        Ok(())
1001    }
1002}
1003
1004/// Possible response to a DNS lookup
1005#[derive(Debug, Clone, Eq, PartialEq, Deftly)]
1006#[derive_deftly(HasMemoryCost)]
1007#[non_exhaustive]
1008pub enum ResolvedVal {
1009    /// We found an IP address
1010    Ip(IpAddr),
1011    /// We found a hostname
1012    Hostname(Vec<u8>),
1013    /// Error; try again
1014    TransientError,
1015    /// Error; don't try again
1016    NontransientError,
1017    /// A DNS lookup response that we didn't recognize
1018    Unrecognized(u8, Vec<u8>),
1019}
1020
1021/// Indicates a hostname response
1022const RES_HOSTNAME: u8 = 0;
1023/// Indicates an IPv4 response
1024const RES_IPV4: u8 = 4;
1025/// Indicates an IPv6 response
1026const RES_IPV6: u8 = 6;
1027/// Transient error (okay to try again)
1028const RES_ERR_TRANSIENT: u8 = 0xF0;
1029/// Non-transient error (don't try again)
1030const RES_ERR_NONTRANSIENT: u8 = 0xF1;
1031
1032impl Readable for ResolvedVal {
1033    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
1034        /// Helper: return the expected length of a resolved answer with
1035        /// a given type, if there is a particular expected length.
1036        fn res_len(tp: u8) -> Option<usize> {
1037            match tp {
1038                RES_IPV4 => Some(4),
1039                RES_IPV6 => Some(16),
1040                _ => None,
1041            }
1042        }
1043        let tp = r.take_u8()?;
1044        let len = r.take_u8()? as usize;
1045        if let Some(expected_len) = res_len(tp) {
1046            if len != expected_len {
1047                return Err(Error::InvalidMessage(
1048                    "Wrong length for RESOLVED answer".into(),
1049                ));
1050            }
1051        }
1052        Ok(match tp {
1053            RES_HOSTNAME => Self::Hostname(r.take(len)?.into()),
1054            RES_IPV4 => Self::Ip(IpAddr::V4(r.extract()?)),
1055            RES_IPV6 => Self::Ip(IpAddr::V6(r.extract()?)),
1056            RES_ERR_TRANSIENT => {
1057                r.advance(len)?;
1058                Self::TransientError
1059            }
1060            RES_ERR_NONTRANSIENT => {
1061                r.advance(len)?;
1062                Self::NontransientError
1063            }
1064            _ => Self::Unrecognized(tp, r.take(len)?.into()),
1065        })
1066    }
1067}
1068
1069impl Writeable for ResolvedVal {
1070    fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
1071        match self {
1072            Self::Hostname(h) => {
1073                w.write_u8(RES_HOSTNAME);
1074                let h_len: u8 = h
1075                    .len()
1076                    .try_into()
1077                    .map_err(|_| EncodeError::BadLengthValue)?;
1078                w.write_u8(h_len);
1079                w.write_all(&h[..]);
1080            }
1081            Self::Ip(IpAddr::V4(a)) => {
1082                w.write_u8(RES_IPV4);
1083                w.write_u8(4); // length
1084                w.write(a)?;
1085            }
1086            Self::Ip(IpAddr::V6(a)) => {
1087                w.write_u8(RES_IPV6);
1088                w.write_u8(16); // length
1089                w.write(a)?;
1090            }
1091            Self::TransientError => {
1092                w.write_u8(RES_ERR_TRANSIENT);
1093                w.write_u8(0); // length
1094            }
1095            Self::NontransientError => {
1096                w.write_u8(RES_ERR_NONTRANSIENT);
1097                w.write_u8(0); // length
1098            }
1099            Self::Unrecognized(tp, v) => {
1100                w.write_u8(*tp);
1101                let v_len: u8 = v
1102                    .len()
1103                    .try_into()
1104                    .map_err(|_| EncodeError::BadLengthValue)?;
1105                w.write_u8(v_len);
1106                w.write_all(&v[..]);
1107            }
1108        }
1109        Ok(())
1110    }
1111}
1112
1113/// A Resolved message is a successful reply to a Resolve message.
1114///
1115/// The Resolved message contains a list of zero or more addresses,
1116/// and their associated times-to-live in seconds.
1117#[derive(Debug, Clone, Deftly)]
1118#[derive_deftly(HasMemoryCost)]
1119pub struct Resolved {
1120    /// List of addresses and their associated time-to-live values.
1121    answers: Vec<(ResolvedVal, u32)>,
1122}
1123impl Resolved {
1124    /// Return a new empty Resolved object with no answers.
1125    pub fn new_empty() -> Self {
1126        Resolved {
1127            answers: Vec::new(),
1128        }
1129    }
1130    /// Return a new Resolved object reporting a name lookup error.
1131    ///
1132    /// TODO: Is getting no answer an error; or it is represented by
1133    /// a list of no answers?
1134    pub fn new_err(transient: bool, ttl: u32) -> Self {
1135        let mut res = Self::new_empty();
1136        let err = if transient {
1137            ResolvedVal::TransientError
1138        } else {
1139            ResolvedVal::NontransientError
1140        };
1141        res.add_answer(err, ttl);
1142        res
1143    }
1144    /// Add a single answer to this Resolved message
1145    pub fn add_answer(&mut self, answer: ResolvedVal, ttl: u32) {
1146        self.answers.push((answer, ttl));
1147    }
1148
1149    /// Consume this Resolved message, returning a vector of the
1150    /// answers and TTL values that it contains.
1151    ///
1152    /// Note that actually relying on these TTL values can be
1153    /// dangerous in practice, since the relay that sent the cell
1154    /// could be lying in order to cause more lookups, or to get a
1155    /// false answer cached for longer.
1156    pub fn into_answers(self) -> Vec<(ResolvedVal, u32)> {
1157        self.answers
1158    }
1159}
1160impl Body for Resolved {
1161    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1162        let mut answers = Vec::new();
1163        while r.remaining() > 0 {
1164            let rv = r.extract()?;
1165            let ttl = r.take_u32()?;
1166            answers.push((rv, ttl));
1167        }
1168        Ok(Resolved { answers })
1169    }
1170    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1171        for (rv, ttl) in &self.answers {
1172            w.write(rv)?;
1173            w.write_u32(*ttl);
1174        }
1175        Ok(())
1176    }
1177}
1178
1179/// A relay message that we didn't recognize
1180///
1181/// NOTE: Clients should generally reject these.
1182#[derive(Debug, Clone, Deftly)]
1183#[derive_deftly(HasMemoryCost)]
1184pub struct Unrecognized {
1185    /// Command that we didn't recognize
1186    cmd: RelayCmd,
1187    /// Body associated with that command
1188    body: Vec<u8>,
1189}
1190
1191impl Unrecognized {
1192    /// Create a new 'unrecognized' cell.
1193    pub fn new<B>(cmd: RelayCmd, body: B) -> Self
1194    where
1195        B: Into<Vec<u8>>,
1196    {
1197        let body = body.into();
1198        Unrecognized { cmd, body }
1199    }
1200
1201    /// Return the command associated with this message
1202    pub fn cmd(&self) -> RelayCmd {
1203        self.cmd
1204    }
1205    /// Decode this message, using a provided command.
1206    pub fn decode_with_cmd(cmd: RelayCmd, r: &mut Reader<'_>) -> Result<Self> {
1207        let mut r = Unrecognized::decode_from_reader(r)?;
1208        r.cmd = cmd;
1209        Ok(r)
1210    }
1211}
1212
1213impl Body for Unrecognized {
1214    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
1215        Ok(Unrecognized {
1216            cmd: 0.into(),
1217            body: r.take(r.remaining())?.into(),
1218        })
1219    }
1220    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
1221        w.write_all(&self.body[..]);
1222        Ok(())
1223    }
1224}
1225
1226/// Declare a message type for a message with an empty body.
1227macro_rules! empty_body {
1228   {
1229       $(#[$meta:meta])*
1230       pub struct $name:ident {}
1231   } => {
1232       $(#[$meta])*
1233       #[derive(Clone,Debug,Default,derive_deftly::Deftly)]
1234       #[derive_deftly(tor_memquota::HasMemoryCost)]
1235       #[non_exhaustive]
1236       pub struct $name {}
1237       impl $crate::relaycell::msg::Body for $name {
1238           fn decode_from_reader(_r: &mut Reader<'_>) -> Result<Self> {
1239               Ok(Self::default())
1240           }
1241           fn encode_onto<W: Writer + ?Sized>(self, _w: &mut W) -> EncodeResult<()> {
1242               Ok(())
1243           }
1244       }
1245   }
1246}
1247pub(crate) use empty_body;
1248
1249empty_body! {
1250    /// A padding message, which is always ignored.
1251    pub struct Drop {}
1252}
1253empty_body! {
1254    /// Tells a circuit to close all downstream hops on the circuit.
1255    pub struct Truncate {}
1256}
1257empty_body! {
1258    /// Opens a new stream on a directory cache.
1259    pub struct BeginDir {}
1260}
1261
1262/// Helper: declare a RelayMsg implementation for a message type that has a
1263/// fixed command.
1264//
1265// TODO: It might be better to merge Body with RelayMsg, but that is complex,
1266// since their needs are _slightly_ different.
1267//
1268// TODO: If we *do* make the change above, then perhaps we should also implement
1269// our restricted enums in terms of this, so that there is only one instance of
1270// [<$body:snake:upper>]
1271macro_rules! msg_impl_relaymsg {
1272    ($($body:ident),* $(,)?) =>
1273    {paste::paste!{
1274       $(impl crate::relaycell::RelayMsg for $body {
1275            fn cmd(&self) -> crate::relaycell::RelayCmd { crate::relaycell::RelayCmd::[< $body:snake:upper >] }
1276            fn encode_onto<W: tor_bytes::Writer + ?Sized>(self, w: &mut W) -> tor_bytes::EncodeResult<()> {
1277                crate::relaycell::msg::Body::encode_onto(self, w)
1278            }
1279            fn decode_from_reader(cmd: RelayCmd, r: &mut tor_bytes::Reader<'_>) -> tor_bytes::Result<Self> {
1280                if cmd != crate::relaycell::RelayCmd::[< $body:snake:upper >] {
1281                    return Err(tor_bytes::Error::InvalidMessage(
1282                        format!("Expected {} command; got {cmd}", stringify!([< $body:snake:upper >])).into()
1283                    ));
1284                }
1285                crate::relaycell::msg::Body::decode_from_reader(r)
1286            }
1287        }
1288
1289        impl TryFrom<AnyRelayMsg> for $body {
1290            type Error = crate::Error;
1291            fn try_from(msg: AnyRelayMsg) -> crate::Result<$body> {
1292                use crate::relaycell::RelayMsg;
1293                match msg {
1294                    AnyRelayMsg::$body(b) => Ok(b),
1295                    _ => Err(crate::Error::CircProto(format!("Expected {}; got {}" ,
1296                                                     stringify!([<$body:snake:upper>]),
1297                                                     msg.cmd())) ),
1298                }
1299            }
1300        }
1301        )*
1302    }}
1303}
1304
1305msg_impl_relaymsg!(
1306    Begin, Data, End, Connected, Sendme, Extend, Extended, Extend2, Extended2, Truncate, Truncated,
1307    Drop, Resolve, Resolved, BeginDir,
1308);
1309
1310#[cfg(feature = "experimental-udp")]
1311msg_impl_relaymsg!(ConnectUdp, ConnectedUdp, Datagram);
1312
1313#[cfg(feature = "hs")]
1314msg_impl_relaymsg!(
1315    EstablishIntro,
1316    EstablishRendezvous,
1317    Introduce1,
1318    Introduce2,
1319    Rendezvous1,
1320    Rendezvous2,
1321    IntroEstablished,
1322    RendezvousEstablished,
1323    IntroduceAck,
1324);
1325
1326#[cfg(feature = "conflux")]
1327msg_impl_relaymsg!(ConfluxSwitch);