1
//! Encoding and decoding for relay messages
2
//!
3
//! Relay messages are sent along circuits, inside RELAY or RELAY_EARLY
4
//! cells.
5

            
6
use super::RelayCmd;
7
use crate::chancell::msg::{DestroyReason, TAP_C_HANDSHAKE_LEN, TAP_S_HANDSHAKE_LEN};
8
use crate::chancell::CELL_DATA_LEN;
9
use caret::caret_int;
10
use educe::Educe;
11
use std::convert::TryInto;
12
use std::net::{IpAddr, Ipv4Addr};
13
use tor_bytes::{Error, Result};
14
use tor_bytes::{Readable, Reader, Writeable, Writer};
15
use tor_linkspec::LinkSpec;
16
use tor_llcrypto::pk::rsa::RsaIdentity;
17

            
18
use bitflags::bitflags;
19

            
20
/// A single parsed relay message, sent or received along a circuit
21
1540
#[derive(Debug, Clone)]
22
#[non_exhaustive]
23
pub enum RelayMsg {
24
    /// Create a stream
25
    Begin(Begin),
26
    /// Send data on a stream
27
    Data(Data),
28
    /// Close a stream
29
    End(End),
30
    /// Successful response to a Begin message
31
    Connected(Connected),
32
    /// For flow control
33
    Sendme(Sendme),
34
    /// Extend a circuit to a new hop (deprecated)
35
    Extend(Extend),
36
    /// Successful response to an Extend message (deprecated)
37
    Extended(Extended),
38
    /// Extend a circuit to a new hop
39
    Extend2(Extend2),
40
    /// Successful response to an Extend2 message
41
    Extended2(Extended2),
42
    /// Partially close a circuit
43
    Truncate,
44
    /// Tell the client the a circuit has been partially closed
45
    Truncated(Truncated),
46
    /// Used for padding
47
    Drop,
48
    /// Launch a DNS request
49
    Resolve(Resolve),
50
    /// Response to a Resolve message
51
    Resolved(Resolved),
52
    /// Start a directory stream
53
    BeginDir,
54

            
55
    /// An unrecognized command.
56
    Unrecognized(Unrecognized),
57
    // No hs for now.
58
}
59

            
60
/// Internal: traits in common different cell bodies.
61
pub trait Body: Sized {
62
    /// Convert this type into a RelayMsg, wrapped appropriate.
63
    fn into_message(self) -> RelayMsg;
64
    /// Decode a relay cell body from a provided reader.
65
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self>;
66
    /// Encode the body of this cell into the end of a vec.
67
    fn encode_onto(self, w: &mut Vec<u8>);
68
}
69

            
70
impl<B: Body> From<B> for RelayMsg {
71
2506
    fn from(b: B) -> RelayMsg {
72
2506
        b.into_message()
73
2506
    }
74
}
75

            
76
impl RelayMsg {
77
    /// Return the stream command associated with this message.
78
57266
    pub fn cmd(&self) -> RelayCmd {
79
57266
        use RelayMsg::*;
80
57266
        match self {
81
242
            Begin(_) => RelayCmd::BEGIN,
82
53350
            Data(_) => RelayCmd::DATA,
83
308
            End(_) => RelayCmd::END,
84
594
            Connected(_) => RelayCmd::CONNECTED,
85
572
            Sendme(_) => RelayCmd::SENDME,
86
22
            Extend(_) => RelayCmd::EXTEND,
87
374
            Extended(_) => RelayCmd::EXTENDED,
88
462
            Extend2(_) => RelayCmd::EXTEND2,
89
836
            Extended2(_) => RelayCmd::EXTENDED2,
90
22
            Truncate => RelayCmd::TRUNCATE,
91
22
            Truncated(_) => RelayCmd::TRUNCATED,
92
22
            Drop => RelayCmd::DROP,
93
66
            Resolve(_) => RelayCmd::RESOLVE,
94
154
            Resolved(_) => RelayCmd::RESOLVED,
95
198
            BeginDir => RelayCmd::BEGIN_DIR,
96
22
            Unrecognized(u) => u.cmd(),
97
        }
98
57266
    }
99
    /// Extract the body of this message from `r`
100
55484
    pub fn decode_from_reader(c: RelayCmd, r: &mut Reader<'_>) -> Result<Self> {
101
55484
        Ok(match c {
102
286
            RelayCmd::BEGIN => RelayMsg::Begin(Begin::decode_from_reader(r)?),
103
53218
            RelayCmd::DATA => RelayMsg::Data(Data::decode_from_reader(r)?),
104
220
            RelayCmd::END => RelayMsg::End(End::decode_from_reader(r)?),
105
352
            RelayCmd::CONNECTED => RelayMsg::Connected(Connected::decode_from_reader(r)?),
106
308
            RelayCmd::SENDME => RelayMsg::Sendme(Sendme::decode_from_reader(r)?),
107
22
            RelayCmd::EXTEND => RelayMsg::Extend(Extend::decode_from_reader(r)?),
108
110
            RelayCmd::EXTENDED => RelayMsg::Extended(Extended::decode_from_reader(r)?),
109
132
            RelayCmd::EXTEND2 => RelayMsg::Extend2(Extend2::decode_from_reader(r)?),
110
286
            RelayCmd::EXTENDED2 => RelayMsg::Extended2(Extended2::decode_from_reader(r)?),
111
22
            RelayCmd::TRUNCATE => RelayMsg::Truncate,
112
22
            RelayCmd::TRUNCATED => RelayMsg::Truncated(Truncated::decode_from_reader(r)?),
113
22
            RelayCmd::DROP => RelayMsg::Drop,
114
66
            RelayCmd::RESOLVE => RelayMsg::Resolve(Resolve::decode_from_reader(r)?),
115
198
            RelayCmd::RESOLVED => RelayMsg::Resolved(Resolved::decode_from_reader(r)?),
116
198
            RelayCmd::BEGIN_DIR => RelayMsg::BeginDir,
117

            
118
22
            _ => RelayMsg::Unrecognized(Unrecognized::decode_with_cmd(c, r)?),
119
        })
120
55484
    }
121
    /// Encode the body of this message, not including command or length
122
56452
    pub fn encode_onto(self, w: &mut Vec<u8>) {
123
56452
        use RelayMsg::*;
124
56452
        match self {
125
308
            Begin(b) => b.encode_onto(w),
126
53240
            Data(b) => b.encode_onto(w),
127
352
            End(b) => b.encode_onto(w),
128
396
            Connected(b) => b.encode_onto(w),
129
352
            Sendme(b) => b.encode_onto(w),
130
44
            Extend(b) => b.encode_onto(w),
131
132
            Extended(b) => b.encode_onto(w),
132
484
            Extend2(b) => b.encode_onto(w),
133
308
            Extended2(b) => b.encode_onto(w),
134
44
            Truncate => (),
135
44
            Truncated(b) => b.encode_onto(w),
136
44
            Drop => (),
137
132
            Resolve(b) => b.encode_onto(w),
138
308
            Resolved(b) => b.encode_onto(w),
139
220
            BeginDir => (),
140
44
            Unrecognized(b) => b.encode_onto(w),
141
        }
142
56452
    }
143
}
144

            
145
bitflags! {
146
    /// A set of recognized flags that can be attached to a begin cell.
147
    ///
148
    /// For historical reasons, these flags are constructed so that 0
149
    /// is a reasonable default for all of them.
150
    pub struct BeginFlags : u32 {
151
        /// The client would accept a connection to an IPv6 address.
152
        const IPV6_OKAY = (1<<0);
153
        /// The client would not accept a connection to an IPv4 address.
154
        const IPV4_NOT_OKAY = (1<<1);
155
        /// The client would rather have a connection to an IPv6 address.
156
        const IPV6_PREFERRED = (1<<2);
157
    }
158
}
159
impl From<u32> for BeginFlags {
160
330
    fn from(v: u32) -> Self {
161
330
        BeginFlags::from_bits_truncate(v)
162
330
    }
163
}
164

            
165
/// A preference for IPv4 vs IPv6 addresses; usable as a nicer frontend for
166
/// BeginFlags.
167
10
#[derive(Clone, Copy, Debug, Eq, PartialEq, Educe)]
168
#[non_exhaustive]
169
#[educe(Default)]
170
pub enum IpVersionPreference {
171
    /// Only IPv4 is allowed.
172
    Ipv4Only,
173
    /// IPv4 and IPv6 are both allowed, and IPv4 is preferred.
174
    #[educe(Default)]
175
    Ipv4Preferred,
176
    /// IPv4 and IPv6 are both allowed, and IPv6 is preferred.
177
    Ipv6Preferred,
178
    /// Only IPv6 is allowed.
179
    Ipv6Only,
180
}
181
impl From<IpVersionPreference> for BeginFlags {
182
176
    fn from(v: IpVersionPreference) -> Self {
183
176
        use IpVersionPreference::*;
184
176
        match v {
185
            Ipv4Only => 0.into(),
186
176
            Ipv4Preferred => BeginFlags::IPV6_OKAY,
187
            Ipv6Preferred => BeginFlags::IPV6_OKAY | BeginFlags::IPV6_PREFERRED,
188
            Ipv6Only => BeginFlags::IPV4_NOT_OKAY,
189
        }
190
176
    }
191
}
192

            
193
/// A Begin message creates a new data stream.
194
///
195
/// Upon receiving a Begin message, relays should try to open a new stream
196
/// for the client, if their exit policy permits, and associate it with a
197
/// new TCP connection to the target address.
198
///
199
/// If the exit decides to reject the Begin message, or if the TCP
200
/// connection fails, the exit should send an End message.
201
///
202
/// Clients should reject these messages.
203
132
#[derive(Debug, Clone)]
204
pub struct Begin {
205
    /// Ascii string describing target address
206
    addr: Vec<u8>,
207
    /// Target port
208
    port: u16,
209
    /// Flags that describe how to resolve the address
210
    flags: BeginFlags,
211
}
212

            
213
impl Begin {
214
    /// Construct a new Begin cell
215
13
    pub fn new<F>(addr: &str, port: u16, flags: F) -> crate::Result<Self>
216
13
    where
217
13
        F: Into<BeginFlags>,
218
13
    {
219
13
        if !addr.is_ascii() {
220
1
            return Err(crate::Error::BadStreamAddress);
221
12
        }
222
12
        let mut addr = addr.to_string();
223
12
        addr.make_ascii_lowercase();
224
12
        Ok(Begin {
225
12
            addr: addr.into_bytes(),
226
12
            port,
227
12
            flags: flags.into(),
228
12
        })
229
13
    }
230
}
231

            
232
impl Body for Begin {
233
264
    fn into_message(self) -> RelayMsg {
234
264
        RelayMsg::Begin(self)
235
264
    }
236
286
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
237
264
        let addr = {
238
286
            if r.peek(1)? == b"[" {
239
                // IPv6 address
240
44
                r.advance(1)?;
241
44
                let a = r.take_until(b']')?;
242
44
                let colon = r.take_u8()?;
243
44
                if colon != b':' {
244
22
                    return Err(Error::BadMessage("missing port in begin cell"));
245
22
                }
246
22
                a
247
            } else {
248
                // IPv4 address, or hostname.
249
242
                r.take_until(b':')?
250
            }
251
        };
252
264
        let port = r.take_until(0)?;
253
264
        let flags = if r.remaining() >= 4 { r.take_u32()? } else { 0 };
254

            
255
264
        if !addr.is_ascii() {
256
22
            return Err(Error::BadMessage("target address in begin cell not ascii"));
257
242
        }
258

            
259
242
        let port = std::str::from_utf8(port)
260
242
            .map_err(|_| Error::BadMessage("port in begin cell not utf8"))?;
261

            
262
242
        let port = port
263
242
            .parse()
264
242
            .map_err(|_| Error::BadMessage("port in begin cell not a valid port"))?;
265

            
266
242
        Ok(Begin {
267
242
            addr: addr.into(),
268
242
            port,
269
242
            flags: flags.into(),
270
242
        })
271
286
    }
272
308
    fn encode_onto(self, w: &mut Vec<u8>) {
273
308
        if self.addr.contains(&b':') {
274
44
            w.write_u8(b'[');
275
44
            w.write_all(&self.addr[..]);
276
44
            w.write_u8(b']');
277
264
        } else {
278
264
            w.write_all(&self.addr[..]);
279
264
        }
280
308
        w.write_u8(b':');
281
308
        w.write_all(self.port.to_string().as_bytes());
282
308
        w.write_u8(0);
283
308
        if self.flags.bits() != 0 {
284
220
            w.write_u32(self.flags.bits());
285
220
        }
286
308
    }
287
}
288

            
289
/// A Data message represents data sent along a stream.
290
///
291
/// Upon receiving a Data message for a live stream, the client or
292
/// exit sends that data onto the associated TCP connection.
293
///
294
/// These messages hold between 1 and [Data::MAXLEN] bytes of data each;
295
/// they are the most numerous messages on the Tor network.
296
88
#[derive(Debug, Clone)]
297
pub struct Data {
298
    /// Contents of the cell, to be sent on a specific stream
299
    body: Vec<u8>,
300
}
301
impl Data {
302
    /// The longest allowable body length for a single data cell.
303
    pub const MAXLEN: usize = CELL_DATA_LEN - 11;
304

            
305
    /// Construct a new data cell.
306
    ///
307
    /// Returns an error if `inp` is longer than [`Data::MAXLEN`] bytes.
308
198
    pub fn new(inp: &[u8]) -> crate::Result<Self> {
309
198
        if inp.len() > Data::MAXLEN {
310
22
            return Err(crate::Error::CantEncode);
311
176
        }
312
176
        Ok(Self::new_unchecked(inp.into()))
313
198
    }
314

            
315
    /// Construct a new data cell, taking as many bytes from `inp`
316
    /// as possible.
317
    ///
318
    /// Return the data cell, and a slice holding any bytes that
319
    /// wouldn't fit (if any).
320
53086
    pub fn split_from(inp: &[u8]) -> (Self, &[u8]) {
321
53086
        let len = std::cmp::min(inp.len(), Data::MAXLEN);
322
53086
        let (data, remainder) = inp.split_at(len);
323
53086
        (Self::new_unchecked(data.into()), remainder)
324
53086
    }
325

            
326
    /// Construct a new data cell from a provided vector of bytes.
327
    ///
328
    /// The vector _must_ have fewer than [`Data::MAXLEN`] bytes.
329
53262
    fn new_unchecked(body: Vec<u8>) -> Self {
330
53262
        Data { body }
331
53262
    }
332
}
333
impl From<Data> for Vec<u8> {
334
72
    fn from(data: Data) -> Vec<u8> {
335
72
        data.body
336
72
    }
337
}
338
impl AsRef<[u8]> for Data {
339
53086
    fn as_ref(&self) -> &[u8] {
340
53086
        &self.body[..]
341
53086
    }
342
}
343

            
344
impl Body for Data {
345
53240
    fn into_message(self) -> RelayMsg {
346
53240
        RelayMsg::Data(self)
347
53240
    }
348
53218
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
349
53218
        Ok(Data {
350
53218
            body: r.take(r.remaining())?.into(),
351
        })
352
53218
    }
353
53240
    fn encode_onto(mut self, w: &mut Vec<u8>) {
354
53240
        w.append(&mut self.body);
355
53240
    }
356
}
357

            
358
/// An End message tells the other end of the circuit to close a stream.
359
///
360
/// Note that End messages do not implement a true half-closed state,
361
/// so after sending an End message each party needs to wait a while
362
/// to be sure that the stream is completely dead.
363
264
#[derive(Debug, Clone)]
364
pub struct End {
365
    /// Reason for closing the stream
366
    reason: EndReason,
367
    /// If the reason is EXITPOLICY, this holds the resolved address an
368
    /// associated TTL.  The TTL is set to MAX if none was given.
369
    addr: Option<(IpAddr, u32)>,
370
}
371

            
372
caret_int! {
373
    /// A declared reason for closing a stream
374
    pub struct EndReason(u8) {
375
        /// Closing a stream because of an unspecified reason.
376
        ///
377
        /// This is the only END reason that clients send.
378
        MISC = 1,
379
        /// Couldn't look up hostname.
380
        RESOLVEFAILED = 2,
381
        /// Remote host refused connection *
382
        CONNECTREFUSED = 3,
383
        /// Closing a stream because of an exit-policy violation.
384
        EXITPOLICY = 4,
385
        /// Circuit destroyed
386
        DESTROY = 5,
387
        /// TCP connection was closed
388
        DONE = 6,
389
        /// Connection timed out, or OR timed out while connecting
390
        TIMEOUT = 7,
391
        /// No route to target destination.
392
        NOROUTE = 8,
393
        /// OR is entering hibernation and not handling requests
394
        HIBERNATING = 9,
395
        /// Internal error at the OR
396
        INTERNAL = 10,
397
        /// Ran out of resources to fulfill requests
398
        RESOURCELIMIT = 11,
399
        /// Connection unexpectedly reset
400
        CONNRESET = 12,
401
        /// Tor protocol violation
402
        TORPROTOCOL = 13,
403
        /// BEGIN_DIR cell at a non-directory-cache.
404
        NOTDIRECTORY = 14,
405
    }
406
}
407

            
408
impl tor_error::HasKind for EndReason {
409
    fn kind(&self) -> tor_error::ErrorKind {
410
        use tor_error::ErrorKind as EK;
411
        use EndReason as E;
412
        match *self {
413
            E::MISC => EK::RemoteStreamError,
414
            E::RESOLVEFAILED => EK::RemoteHostNotFound,
415
            E::CONNECTREFUSED => EK::RemoteConnectionRefused,
416
            E::EXITPOLICY => EK::ExitPolicyRejected,
417
            E::DESTROY => EK::CircuitCollapse,
418
            E::DONE => EK::RemoteStreamClosed,
419
            E::TIMEOUT => EK::ExitTimeout,
420
            E::NOROUTE => EK::RemoteNetworkFailed,
421
            E::RESOURCELIMIT | E::HIBERNATING => EK::RelayTooBusy,
422
            E::INTERNAL | E::TORPROTOCOL | E::NOTDIRECTORY => EK::TorProtocolViolation,
423
            E::CONNRESET => EK::RemoteStreamReset,
424
            _ => EK::RemoteStreamError,
425
        }
426
    }
427
}
428

            
429
impl End {
430
    /// Make a new END_REASON_MISC message.
431
    ///
432
    /// Clients send this every time they decide to close a stream.
433
44
    pub fn new_misc() -> Self {
434
44
        End {
435
44
            reason: EndReason::MISC,
436
44
            addr: None,
437
44
        }
438
44
    }
439
    /// Make a new END message with the provided end reason.
440
110
    pub fn new_with_reason(reason: EndReason) -> Self {
441
110
        End { reason, addr: None }
442
110
    }
443
    /// Make a new END message with END_REASON_EXITPOLICY, and the
444
    /// provided address and ttl.
445
66
    pub fn new_exitpolicy(addr: IpAddr, ttl: u32) -> Self {
446
66
        End {
447
66
            reason: EndReason::EXITPOLICY,
448
66
            addr: Some((addr, ttl)),
449
66
        }
450
66
    }
451
    /// Return the provided EndReason for this End cell.
452
88
    pub fn reason(&self) -> EndReason {
453
88
        self.reason
454
88
    }
455
}
456
impl Body for End {
457
220
    fn into_message(self) -> RelayMsg {
458
220
        RelayMsg::End(self)
459
220
    }
460
220
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
461
220
        if r.remaining() == 0 {
462
22
            return Ok(End {
463
22
                reason: EndReason::MISC,
464
22
                addr: None,
465
22
            });
466
198
        }
467
198
        let reason = r.take_u8()?.into();
468
198
        if reason == EndReason::EXITPOLICY {
469
66
            let addr = match r.remaining() {
470
44
                4 | 8 => IpAddr::V4(r.extract()?),
471
22
                16 | 20 => IpAddr::V6(r.extract()?),
472
                _ => {
473
                    // Ignores other message lengths.
474
                    return Ok(End { reason, addr: None });
475
                }
476
            };
477
66
            let ttl = if r.remaining() == 4 {
478
44
                r.take_u32()?
479
            } else {
480
22
                u32::MAX
481
            };
482
66
            Ok(End {
483
66
                reason,
484
66
                addr: Some((addr, ttl)),
485
66
            })
486
        } else {
487
132
            Ok(End { reason, addr: None })
488
        }
489
220
    }
490
352
    fn encode_onto(self, w: &mut Vec<u8>) {
491
352
        w.write_u8(self.reason.into());
492
352
        if let (EndReason::EXITPOLICY, Some((addr, ttl))) = (self.reason, self.addr) {
493
132
            match addr {
494
88
                IpAddr::V4(v4) => w.write(&v4),
495
44
                IpAddr::V6(v6) => w.write(&v6),
496
            }
497
132
            w.write_u32(ttl);
498
220
        }
499
352
    }
500
}
501

            
502
impl From<EndReason> for std::io::ErrorKind {
503
    fn from(e: EndReason) -> Self {
504
        use std::io::ErrorKind::*;
505
        match e {
506
            EndReason::RESOLVEFAILED => NotFound,
507
            EndReason::CONNECTREFUSED => ConnectionRefused,
508
            EndReason::EXITPOLICY => ConnectionRefused,
509
            EndReason::DESTROY => ConnectionAborted,
510
            EndReason::DONE => UnexpectedEof,
511
            EndReason::TIMEOUT => TimedOut,
512
            EndReason::HIBERNATING => ConnectionRefused,
513
            EndReason::RESOURCELIMIT => ConnectionRefused,
514
            EndReason::CONNRESET => ConnectionReset,
515
            EndReason::TORPROTOCOL => InvalidData,
516
            EndReason::NOTDIRECTORY => ConnectionRefused,
517
            EndReason::INTERNAL | EndReason::NOROUTE | EndReason::MISC => Other,
518
            _ => Other,
519
        }
520
    }
521
}
522

            
523
/// A Connected message is a successful response to a Begin message
524
///
525
/// When an outgoing connection succeeds, the exit sends a Connected
526
/// back to the client.
527
///
528
/// Clients never send Connected messages.
529
132
#[derive(Debug, Clone)]
530
pub struct Connected {
531
    /// Resolved address and TTL (time to live) in seconds
532
    addr: Option<(IpAddr, u32)>,
533
}
534
impl Connected {
535
    /// Construct a new empty connected cell.
536
308
    pub fn new_empty() -> Self {
537
308
        Connected { addr: None }
538
308
    }
539
    /// Construct a connected cell with an address and a time-to-live value.
540
44
    pub fn new_with_addr(addr: IpAddr, ttl: u32) -> Self {
541
44
        Connected {
542
44
            addr: Some((addr, ttl)),
543
44
        }
544
44
    }
545
}
546
impl Body for Connected {
547
352
    fn into_message(self) -> RelayMsg {
548
352
        RelayMsg::Connected(self)
549
352
    }
550
352
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
551
352
        if r.remaining() == 0 {
552
286
            return Ok(Connected { addr: None });
553
66
        }
554
66
        let ipv4 = r.take_u32()?;
555
66
        let addr = if ipv4 == 0 {
556
44
            if r.take_u8()? != 6 {
557
22
                return Err(Error::BadMessage("Invalid address type in CONNECTED cell"));
558
22
            }
559
22
            IpAddr::V6(r.extract()?)
560
        } else {
561
22
            IpAddr::V4(ipv4.into())
562
        };
563
44
        let ttl = r.take_u32()?;
564

            
565
44
        Ok(Connected {
566
44
            addr: Some((addr, ttl)),
567
44
        })
568
352
    }
569
    fn encode_onto(self, w: &mut Vec<u8>) {
570
396
        if let Some((addr, ttl)) = self.addr {
571
88
            match addr {
572
44
                IpAddr::V4(v4) => w.write(&v4),
573
44
                IpAddr::V6(v6) => {
574
44
                    w.write_u32(0);
575
44
                    w.write_u8(6);
576
44
                    w.write(&v6);
577
44
                }
578
            }
579
88
            w.write_u32(ttl);
580
308
        }
581
396
    }
582
}
583

            
584
/// A Sendme message is used to increase flow-control windows.
585
///
586
/// To avoid congestion, each Tor circuit and stream keeps track of a
587
/// number of data cells that it is willing to send.  It decrements
588
/// these numbers every time it sends a cell.  If these numbers reach
589
/// zero, then no more cells can be sent on the stream or circuit.
590
///
591
/// The only way to re-increment these numbers is by receiving a
592
/// Sendme cell from the other end of the circuit or stream.
593
///
594
/// For security, current circuit-level Sendme cells include an
595
/// authentication tag that proves knowledge of the cells that they are
596
/// acking.
597
///
598
/// See [tor-spec.txt](https://spec.torproject.org/tor-spec) for more
599
/// information; also see the source for `tor_proto::circuit::sendme`.
600
88
#[derive(Debug, Clone)]
601
pub struct Sendme {
602
    /// A tag value authenticating the previously received data.
603
    digest: Option<Vec<u8>>,
604
}
605
impl Sendme {
606
    /// Return a new empty sendme cell
607
    ///
608
    /// This format is used on streams, and on circuits without sendme
609
    /// authentication.
610
132
    pub fn new_empty() -> Self {
611
132
        Sendme { digest: None }
612
132
    }
613
    /// This format is used on circuits with sendme authentication.
614
198
    pub fn new_tag(x: [u8; 20]) -> Self {
615
198
        Sendme {
616
198
            digest: Some(x.into()),
617
198
        }
618
198
    }
619
    /// Consume this cell and return its authentication tag, if any
620
176
    pub fn into_tag(self) -> Option<Vec<u8>> {
621
176
        self.digest
622
176
    }
623
}
624
impl Body for Sendme {
625
330
    fn into_message(self) -> RelayMsg {
626
330
        RelayMsg::Sendme(self)
627
330
    }
628
308
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
629
308
        let digest = if r.remaining() == 0 {
630
110
            None
631
        } else {
632
198
            let ver = r.take_u8()?;
633
198
            match ver {
634
                0 => None,
635
                1 => {
636
198
                    let dlen = r.take_u16()?;
637
198
                    Some(r.take(dlen as usize)?.into())
638
                }
639
                _ => {
640
                    return Err(Error::BadMessage("Unrecognized SENDME version."));
641
                }
642
            }
643
        };
644
308
        Ok(Sendme { digest })
645
308
    }
646
352
    fn encode_onto(self, w: &mut Vec<u8>) {
647
352
        match self.digest {
648
132
            None => (),
649
220
            Some(mut x) => {
650
220
                w.write_u8(1);
651
220
                let bodylen: u16 = x
652
220
                    .len()
653
220
                    .try_into()
654
220
                    .expect("Too many bytes to encode in relay cell.");
655
220
                w.write_u16(bodylen);
656
220
                w.append(&mut x);
657
220
            }
658
        }
659
352
    }
660
}
661

            
662
/// Extend was an obsolete circuit extension message format.
663
///
664
/// This format only handled IPv4 addresses, RSA identities, and the
665
/// TAP handshake.  Modern Tor clients use Extend2 instead.
666
44
#[derive(Debug, Clone)]
667
pub struct Extend {
668
    /// Where to extend to (address)
669
    addr: Ipv4Addr,
670
    /// Where to extend to (port)
671
    port: u16,
672
    /// A TAP handshake to send
673
    handshake: Vec<u8>,
674
    /// The RSA identity of the target relay
675
    rsaid: RsaIdentity,
676
}
677
impl Extend {
678
    /// Construct a new (deprecated) extend cell
679
22
    pub fn new(addr: Ipv4Addr, port: u16, handshake: Vec<u8>, rsaid: RsaIdentity) -> Self {
680
22
        Extend {
681
22
            addr,
682
22
            port,
683
22
            handshake,
684
22
            rsaid,
685
22
        }
686
22
    }
687
}
688
impl Body for Extend {
689
22
    fn into_message(self) -> RelayMsg {
690
22
        RelayMsg::Extend(self)
691
22
    }
692
22
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
693
22
        let addr = r.extract()?;
694
22
        let port = r.take_u16()?;
695
22
        let handshake = r.take(TAP_C_HANDSHAKE_LEN)?.into();
696
22
        let rsaid = r.extract()?;
697
22
        Ok(Extend {
698
22
            addr,
699
22
            port,
700
22
            handshake,
701
22
            rsaid,
702
22
        })
703
22
    }
704
44
    fn encode_onto(self, w: &mut Vec<u8>) {
705
44
        w.write(&self.addr);
706
44
        w.write_u16(self.port);
707
44
        w.write_all(&self.handshake[..]);
708
44
        w.write(&self.rsaid);
709
44
    }
710
}
711

            
712
/// Extended was an obsolete circuit extension message, sent in reply to
713
/// an Extend message.
714
///
715
/// Like Extend, the Extended message was only designed for the TAP
716
/// handshake.
717
44
#[derive(Debug, Clone)]
718
pub struct Extended {
719
    /// Contents of the handshake sent in response to the EXTEND
720
    handshake: Vec<u8>,
721
}
722
impl Extended {
723
    /// Construct a new Extended message with the provided handshake
724
110
    pub fn new(handshake: Vec<u8>) -> Self {
725
110
        Extended { handshake }
726
110
    }
727
}
728
impl Body for Extended {
729
110
    fn into_message(self) -> RelayMsg {
730
110
        RelayMsg::Extended(self)
731
110
    }
732
110
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
733
110
        let handshake = r.take(TAP_S_HANDSHAKE_LEN)?.into();
734
110
        Ok(Extended { handshake })
735
110
    }
736
132
    fn encode_onto(mut self, w: &mut Vec<u8>) {
737
132
        w.append(&mut self.handshake);
738
132
    }
739
}
740

            
741
/// An Extend2 message tells the last relay in a circuit to extend to a new
742
/// hop.
743
///
744
/// When a relay (call it R) receives an Extend2 message, it tries to
745
/// find (or make) a channel to the other relay (R') described in the
746
/// list of link specifiers. (A link specifier can be an IP addresses
747
/// or a cryptographic identity).  Once R has such a channel, the
748
/// it packages the client's handshake data as a new Create2 message
749
/// R'.  If R' replies with a Created2 (success) message, R packages
750
/// that message's contents in an Extended message.
751
//
752
/// Unlike Extend messages, Extend2 messages can encode any handshake
753
/// type, and can describe relays in ways other than IPv4 addresses
754
/// and RSA identities.
755
44
#[derive(Debug, Clone)]
756
pub struct Extend2 {
757
    /// A vector of "link specifiers"
758
    ///
759
    /// These link specifiers describe where to find the target relay
760
    /// that the recipient should extend to.  They include things like
761
    /// IP addresses and identity keys.
762
    linkspec: Vec<LinkSpec>,
763
    /// Type of handshake to be sent in a CREATE2 cell
764
    handshake_type: u16,
765
    /// Body of the handshake to be sent in a CREATE2 cell
766
    handshake: Vec<u8>,
767
}
768
impl Extend2 {
769
    /// Create a new Extend2 cell.
770
462
    pub fn new(mut linkspec: Vec<LinkSpec>, handshake_type: u16, handshake: Vec<u8>) -> Self {
771
462
        LinkSpec::sort_by_type(linkspec.as_mut());
772
462

            
773
462
        Extend2 {
774
462
            linkspec,
775
462
            handshake_type,
776
462
            handshake,
777
462
        }
778
462
    }
779

            
780
    /// Return the type of this handshake.
781
22
    pub fn handshake_type(&self) -> u16 {
782
22
        self.handshake_type
783
22
    }
784

            
785
    /// Return the inner handshake for this Extend2 cell.
786
110
    pub fn handshake(&self) -> &[u8] {
787
110
        &self.handshake[..]
788
110
    }
789
}
790

            
791
impl Body for Extend2 {
792
462
    fn into_message(self) -> RelayMsg {
793
462
        RelayMsg::Extend2(self)
794
462
    }
795
132
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
796
132
        let n = r.take_u8()?;
797
132
        let linkspec = r.extract_n(n as usize)?;
798
132
        let handshake_type = r.take_u16()?;
799
132
        let hlen = r.take_u16()?;
800
132
        let handshake = r.take(hlen as usize)?.into();
801
132
        Ok(Extend2 {
802
132
            linkspec,
803
132
            handshake_type,
804
132
            handshake,
805
132
        })
806
132
    }
807
484
    fn encode_onto(self, w: &mut Vec<u8>) {
808
484
        let n_linkspecs: u8 = self.linkspec.len().try_into().expect("Too many linkspecs");
809
484
        w.write_u8(n_linkspecs);
810
1452
        for ls in &self.linkspec {
811
968
            w.write(ls);
812
968
        }
813
484
        w.write_u16(self.handshake_type);
814
484
        let handshake_len: u16 = self.handshake.len().try_into().expect("Handshake too long");
815
484
        w.write_u16(handshake_len);
816
484
        w.write_all(&self.handshake[..]);
817
484
    }
818
}
819

            
820
/// Extended2 is a successful reply to an Extend2 message.
821
///
822
/// Extended2 messages are generated by the former last hop of a
823
/// circuit, to tell the client that they have successfully completed
824
/// a handshake on the client's behalf.
825
44
#[derive(Debug, Clone)]
826
pub struct Extended2 {
827
    /// Contents of the CREATED2 cell that the new final hop sent in
828
    /// response
829
    handshake: Vec<u8>,
830
}
831
impl Extended2 {
832
    /// Construct a new Extended2 message with the provided handshake
833
308
    pub fn new(handshake: Vec<u8>) -> Self {
834
308
        Extended2 { handshake }
835
308
    }
836
    /// Consume this extended2 cell and return its body.
837
176
    pub fn into_body(self) -> Vec<u8> {
838
176
        self.handshake
839
176
    }
840
}
841
impl Body for Extended2 {
842
308
    fn into_message(self) -> RelayMsg {
843
308
        RelayMsg::Extended2(self)
844
308
    }
845
286
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
846
286
        let hlen = r.take_u16()?;
847
286
        let handshake = r.take(hlen as usize)?;
848
286
        Ok(Extended2 {
849
286
            handshake: handshake.into(),
850
286
        })
851
286
    }
852
308
    fn encode_onto(self, w: &mut Vec<u8>) {
853
308
        let handshake_len: u16 = self.handshake.len().try_into().expect("Handshake too long");
854
308
        w.write_u16(handshake_len);
855
308
        w.write_all(&self.handshake[..]);
856
308
    }
857
}
858

            
859
/// A Truncated message is sent to the client when the remaining hops
860
/// of a circuit have gone away.
861
///
862
/// NOTE: Current Tor implementations often treat Truncated messages and
863
/// Destroy messages interchangeably.  Truncated was intended to be a
864
/// "soft" Destroy, that would leave the unaffected parts of a circuit
865
/// still usable.
866
44
#[derive(Debug, Clone)]
867
pub struct Truncated {
868
    /// Reason for which this circuit was truncated.
869
    reason: DestroyReason,
870
}
871
impl Truncated {
872
    /// Construct a new truncated message.
873
22
    pub fn new(reason: DestroyReason) -> Self {
874
22
        Truncated { reason }
875
22
    }
876
    /// Get the provided reason to truncate the circuit.
877
    pub fn reason(self) -> DestroyReason {
878
        self.reason
879
    }
880
}
881
impl Body for Truncated {
882
22
    fn into_message(self) -> RelayMsg {
883
22
        RelayMsg::Truncated(self)
884
22
    }
885
22
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
886
22
        Ok(Truncated {
887
22
            reason: r.take_u8()?.into(),
888
        })
889
22
    }
890
44
    fn encode_onto(self, w: &mut Vec<u8>) {
891
44
        w.write_u8(self.reason.into());
892
44
    }
893
}
894

            
895
/// A Resolve message launches a DNS lookup stream.
896
///
897
/// A client sends a Resolve message when it wants to perform a DNS
898
/// lookup _without_ connecting to the resulting address.  On success
899
/// the exit responds with a Resolved message; on failure it responds
900
/// with an End message.
901
132
#[derive(Debug, Clone)]
902
pub struct Resolve {
903
    /// Ascii-encoded address to resolve
904
    query: Vec<u8>,
905
}
906
impl Resolve {
907
    /// Construct a new resolve message to look up a hostname.
908
22
    pub fn new(s: &str) -> Self {
909
22
        Resolve {
910
22
            query: s.as_bytes().into(),
911
22
        }
912
22
    }
913
    /// Construct a new resolve message to do a reverse lookup on an address
914
44
    pub fn new_reverse(addr: &IpAddr) -> Self {
915
44
        let query = match addr {
916
22
            IpAddr::V4(v4) => {
917
22
                let [a, b, c, d] = v4.octets();
918
22
                format!("{}.{}.{}.{}.in-addr.arpa", d, c, b, a)
919
            }
920
22
            IpAddr::V6(v6) => {
921
22
                let mut s = String::with_capacity(72);
922
352
                for o in v6.octets().iter().rev() {
923
352
                    let high_nybble = o >> 4;
924
352
                    let low_nybble = o & 15;
925
352
                    s.push_str(&format!("{:x}.{:x}.", low_nybble, high_nybble));
926
352
                }
927
22
                s.push_str("ip6.arpa");
928
22
                s
929
            }
930
        };
931
44
        Resolve {
932
44
            query: query.into_bytes(),
933
44
        }
934
44
    }
935
}
936
impl Body for Resolve {
937
66
    fn into_message(self) -> RelayMsg {
938
66
        RelayMsg::Resolve(self)
939
66
    }
940
66
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
941
66
        let query = r.take_until(0)?;
942
66
        Ok(Resolve {
943
66
            query: query.into(),
944
66
        })
945
66
    }
946
132
    fn encode_onto(self, w: &mut Vec<u8>) {
947
132
        w.write_all(&self.query[..]);
948
132
        w.write_u8(0);
949
132
    }
950
}
951

            
952
/// Possible response to a DNS lookup
953
308
#[derive(Debug, Clone, Eq, PartialEq)]
954
#[non_exhaustive]
955
pub enum ResolvedVal {
956
    /// We found an IP address
957
    Ip(IpAddr),
958
    /// We found a hostname
959
    Hostname(Vec<u8>),
960
    /// Error; try again
961
    TransientError,
962
    /// Error; don't try again
963
    NontransientError,
964
    /// A DNS lookup response that we didn't recognize
965
    Unrecognized(u8, Vec<u8>),
966
}
967
/// Indicates a hostname response
968
const RES_HOSTNAME: u8 = 0;
969
/// Indicates an IPv4 response
970
const RES_IPV4: u8 = 4;
971
/// Indicates an IPv6 response
972
const RES_IPV6: u8 = 6;
973
/// Transient error (okay to try again)
974
const RES_ERR_TRANSIENT: u8 = 0xF0;
975
/// Non-transient error (don't try again)
976
const RES_ERR_NONTRANSIENT: u8 = 0xF1;
977

            
978
impl Readable for ResolvedVal {
979
198
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
980
        /// Helper: return the expected length of a resolved answer with
981
        /// a given type, if there is a particular expected length.
982
198
        fn res_len(tp: u8) -> Option<usize> {
983
198
            match tp {
984
66
                RES_IPV4 => Some(4),
985
44
                RES_IPV6 => Some(16),
986
88
                _ => None,
987
            }
988
198
        }
989
198
        let tp = r.take_u8()?;
990
198
        let len = r.take_u8()? as usize;
991
198
        if let Some(expected_len) = res_len(tp) {
992
110
            if len != expected_len {
993
22
                return Err(Error::BadMessage("Wrong length for RESOLVED answer"));
994
88
            }
995
88
        }
996
176
        Ok(match tp {
997
22
            RES_HOSTNAME => Self::Hostname(r.take(len)?.into()),
998
44
            RES_IPV4 => Self::Ip(IpAddr::V4(r.extract()?)),
999
44
            RES_IPV6 => Self::Ip(IpAddr::V6(r.extract()?)),
            RES_ERR_TRANSIENT => {
22
                r.advance(len)?;
22
                Self::TransientError
            }
            RES_ERR_NONTRANSIENT => {
22
                r.advance(len)?;
22
                Self::NontransientError
            }
22
            _ => Self::Unrecognized(tp, r.take(len)?.into()),
        })
198
    }
}

            
impl Writeable for ResolvedVal {
    fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) {
132
        match self {
44
            Self::Hostname(h) => {
44
                w.write_u8(RES_HOSTNAME);
44
                let h_len: u8 = h.len().try_into().expect("Hostname too long");
44
                w.write_u8(h_len);
44
                w.write_all(&h[..]);
44
            }
88
            Self::Ip(IpAddr::V4(a)) => {
88
                w.write_u8(RES_IPV4);
88
                w.write_u8(4); // length
88
                w.write(a);
88
            }
44
            Self::Ip(IpAddr::V6(a)) => {
44
                w.write_u8(RES_IPV6);
44
                w.write_u8(16); // length
44
                w.write(a);
44
            }
44
            Self::TransientError => {
44
                w.write_u8(RES_ERR_TRANSIENT);
44
                w.write_u8(0); // length
44
            }
44
            Self::NontransientError => {
44
                w.write_u8(RES_ERR_NONTRANSIENT);
44
                w.write_u8(0); // length
44
            }
44
            Self::Unrecognized(tp, v) => {
44
                w.write_u8(*tp);
44
                let v_len: u8 = v
44
                    .len()
44
                    .try_into()
44
                    .expect("Unrecognized resolved entry too long");
44
                w.write_u8(v_len);
44
                w.write_all(&v[..]);
44
            }
        }
308
    }
}

            
/// A Resolved message is a successful reply to a Resolve message.
///
/// The Resolved message contains a list of zero or more addresses,
/// and their associated times-to-live in seconds.
308
#[derive(Debug, Clone)]
pub struct Resolved {
    /// List of addresses and their associated time-to-live values.
    answers: Vec<(ResolvedVal, u32)>,
}
impl Resolved {
    /// Return a new empty Resolved object with no answers.
154
    pub fn new_empty() -> Self {
154
        Resolved {
154
            answers: Vec::new(),
154
        }
154
    }
    /// Return a new Resolved object reporting a name lookup error.
    ///
    /// TODO: Is getting no answer an error; or it is represented by
    /// a list of no answers?
44
    pub fn new_err(transient: bool, ttl: u32) -> Self {
44
        let mut res = Self::new_empty();
44
        let err = if transient {
22
            ResolvedVal::TransientError
        } else {
22
            ResolvedVal::NontransientError
        };
44
        res.add_answer(err, ttl);
44
        res
44
    }
    /// Add a single answer to this Resolved message
154
    pub fn add_answer(&mut self, answer: ResolvedVal, ttl: u32) {
154
        self.answers.push((answer, ttl));
154
    }

            
    /// Consume this Resolved message, returning a vector of the
    /// answers and TTL values that it contains.
    ///
    /// Note that actually relying on these TTL values can be
    /// dangerous in practice, since the relay that sent the cell
    /// could be lying in order to cause more lookups, or to get a
    /// false answer cached for longer.
22
    pub fn into_answers(self) -> Vec<(ResolvedVal, u32)> {
22
        self.answers
22
    }
}
impl Body for Resolved {
154
    fn into_message(self) -> RelayMsg {
154
        RelayMsg::Resolved(self)
154
    }
198
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
198
        let mut answers = Vec::new();
374
        while r.remaining() > 0 {
198
            let rv = r.extract()?;
176
            let ttl = r.take_u32()?;
176
            answers.push((rv, ttl));
        }
176
        Ok(Resolved { answers })
198
    }
308
    fn encode_onto(self, w: &mut Vec<u8>) {
616
        for (rv, ttl) in &self.answers {
308
            w.write(rv);
308
            w.write_u32(*ttl);
308
        }
308
    }
}

            
/// A relay message that we didn't recognize
///
/// NOTE: Clients should generally reject these.
44
#[derive(Debug, Clone)]
pub struct Unrecognized {
    /// Command that we didn't recognize
    cmd: RelayCmd,
    /// Body associated with that command
    body: Vec<u8>,
}

            
impl Unrecognized {
    /// Create a new 'unrecognized' cell.
1
    pub fn new<B>(cmd: RelayCmd, body: B) -> Self
1
    where
1
        B: Into<Vec<u8>>,
1
    {
1
        let body = body.into();
1
        Unrecognized { cmd, body }
1
    }

            
    /// Return the command associated with this message
22
    pub fn cmd(&self) -> RelayCmd {
22
        self.cmd
22
    }
    /// Decode this message, using a provided command.
22
    pub fn decode_with_cmd(cmd: RelayCmd, r: &mut Reader<'_>) -> Result<Self> {
22
        let mut r = Unrecognized::decode_from_reader(r)?;
22
        r.cmd = cmd;
22
        Ok(r)
22
    }
}

            
impl Body for Unrecognized {
22
    fn into_message(self) -> RelayMsg {
22
        RelayMsg::Unrecognized(self)
22
    }
22
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
22
        Ok(Unrecognized {
22
            cmd: 0.into(),
22
            body: r.take(r.remaining())?.into(),
        })
22
    }
44
    fn encode_onto(self, w: &mut Vec<u8>) {
44
        w.write_all(&self.body[..]);
44
    }
}