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::msg;
7
use crate::chancell::CELL_DATA_LEN;
8
use derive_deftly::Deftly;
9
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
10
use std::str::FromStr;
11
use tor_bytes::{EncodeResult, Error, Result};
12
use tor_bytes::{Readable, Reader, Writeable, Writer};
13
use tor_memquota::derive_deftly_template_HasMemoryCost;
14

            
15
/// Indicates the payload is a hostname.
16
const T_HOSTNAME: u8 = 0x01;
17
/// Indicates the payload is an IPv4.
18
const T_IPV4: u8 = 0x04;
19
/// Indicates the payload is an IPv6.
20
const T_IPV6: u8 = 0x06;
21

            
22
/// Maximum length of an Address::Hostname set at 255.
23
const MAX_HOSTNAME_LEN: usize = u8::MAX as usize;
24

            
25
/// Address contained in a ConnectUdp and ConnectedUdp cell which can
26
/// represent a hostname, IPv4 or IPv6 along a port number.
27
#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
28
#[derive_deftly(HasMemoryCost)]
29
pub struct AddressPort {
30
    /// Address.
31
    addr: Address,
32
    /// Port.
33
    port: u16,
34
}
35

            
36
impl Readable for AddressPort {
37
1155
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
38
1155
        Ok(Self {
39
1155
            addr: r.extract()?,
40
715
            port: r.take_u16()?,
41
        })
42
1155
    }
43
}
44

            
45
impl Writeable for AddressPort {
46
36
    fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
47
36
        w.write(&self.addr)?;
48
36
        w.write_u16(self.port);
49
36
        Ok(())
50
36
    }
51
}
52

            
53
impl TryFrom<(&str, u16)> for AddressPort {
54
    type Error = Error;
55

            
56
495
    fn try_from(value: (&str, u16)) -> Result<Self> {
57
495
        let addr = Address::from_str(value.0)?;
58
495
        Ok(Self {
59
495
            addr,
60
495
            port: value.1,
61
495
        })
62
495
    }
63
}
64

            
65
/// Address representing either a hostname, IPv4 or IPv6.
66
#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
67
#[derive_deftly(HasMemoryCost)]
68
#[non_exhaustive]
69
pub enum Address {
70
    /// Hostname
71
    Hostname(Vec<u8>),
72
    /// IP version 4 address
73
    Ipv4(Ipv4Addr),
74
    /// IP version 6 address
75
    Ipv6(Ipv6Addr),
76
}
77

            
78
impl Address {
79
    /// Return true iff this is a Hostname.
80
880
    pub fn is_hostname(&self) -> bool {
81
880
        matches!(self, Address::Hostname(_))
82
880
    }
83

            
84
    /// Return the cell wire format address type value.
85
990
    fn wire_addr_type(&self) -> u8 {
86
990
        match self {
87
330
            Address::Hostname(_) => T_HOSTNAME,
88
330
            Address::Ipv4(_) => T_IPV4,
89
330
            Address::Ipv6(_) => T_IPV6,
90
        }
91
990
    }
92
}
93

            
94
impl Readable for Address {
95
1155
    fn take_from(r: &mut Reader<'_>) -> Result<Self> {
96
1155
        let addr_type = r.take_u8()?;
97
1175
        r.read_nested_u8len(|r| {
98
1100
            Ok(match addr_type {
99
                T_HOSTNAME => {
100
330
                    let h = r.take_rest();
101
330
                    Self::Hostname(h.into())
102
                }
103
385
                T_IPV4 => Self::Ipv4(r.extract()?),
104
330
                T_IPV6 => Self::Ipv6(r.extract()?),
105
55
                _ => return Err(Error::InvalidMessage("Invalid address type".into())),
106
            })
107
1175
        })
108
1155
    }
109
}
110

            
111
impl Writeable for Address {
112
36
    fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
113
36
        // Address type.
114
36
        w.write_u8(self.wire_addr_type());
115
36
        // Address length and data.
116
36
        let mut w = w.write_nested_u8len();
117
36

            
118
36
        match self {
119
12
            Address::Hostname(h) => {
120
12
                w.write_all(&h[..]);
121
12
            }
122
12
            Address::Ipv4(ip) => w.write(ip)?,
123
12
            Address::Ipv6(ip) => w.write(ip)?,
124
        }
125

            
126
36
        w.finish()
127
36
    }
128
}
129

            
130
impl FromStr for Address {
131
    type Err = Error;
132

            
133
1210
    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
134
1210
        if let Ok(ipv4) = Ipv4Addr::from_str(s) {
135
220
            Ok(Self::Ipv4(ipv4))
136
990
        } else if let Ok(ipv6) = Ipv6Addr::from_str(s) {
137
220
            Ok(Self::Ipv6(ipv6))
138
        } else {
139
770
            if s.len() > MAX_HOSTNAME_LEN {
140
55
                return Err(Error::InvalidMessage("Hostname too long".into()));
141
715
            }
142
715
            if s.contains('\0') {
143
55
                return Err(Error::InvalidMessage("Nul byte not permitted".into()));
144
660
            }
145
660

            
146
660
            let mut addr = s.to_string();
147
660
            addr.make_ascii_lowercase();
148
660
            Ok(Self::Hostname(addr.into_bytes()))
149
        }
150
1210
    }
151
}
152

            
153
impl From<IpAddr> for Address {
154
    fn from(ip: IpAddr) -> Self {
155
        match ip {
156
            IpAddr::V4(ip) => Address::Ipv4(ip),
157
            IpAddr::V6(ip) => Address::Ipv6(ip),
158
        }
159
    }
160
}
161

            
162
/// A ConnectUdp message creates a new UDP data stream.
163
///
164
/// Upon receiving a ConnectUdp message, a relay tries to connect to the given address with the UDP
165
/// protocol if the exit policy permits.
166
///
167
/// If the exit decides to reject the message, or if the UDP connection fails, the exit should send
168
/// an End message.
169
///
170
/// Clients should reject these messages.
171
#[derive(Debug, Clone, Deftly)]
172
#[derive_deftly(HasMemoryCost)]
173
pub struct ConnectUdp {
174
    /// Same as Begin flags.
175
    flags: msg::BeginFlags,
176
    /// Address to connect to. Can be Hostname, IPv4 or IPv6.
177
    addr: AddressPort,
178
}
179

            
180
impl ConnectUdp {
181
    /// Construct a new ConnectUdp cell
182
10
    pub fn new<F>(addr: &str, port: u16, flags: F) -> crate::Result<Self>
183
10
    where
184
10
        F: Into<msg::BeginFlags>,
185
10
    {
186
10
        Ok(Self {
187
10
            addr: (addr, port)
188
10
                .try_into()
189
10
                .map_err(|_| crate::Error::BadStreamAddress)?,
190
10
            flags: flags.into(),
191
        })
192
10
    }
193
}
194

            
195
impl msg::Body for ConnectUdp {
196
770
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
197
770
        let flags = r.take_u32()?;
198
770
        let addr = r.extract()?;
199

            
200
330
        Ok(Self {
201
330
            flags: flags.into(),
202
330
            addr,
203
330
        })
204
770
    }
205

            
206
20
    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
207
20
        w.write_u32(self.flags.bits());
208
20
        w.write(&self.addr)?;
209
20
        Ok(())
210
20
    }
211
}
212

            
213
/// A ConnectedUdp cell sent in response to a ConnectUdp.
214
#[derive(Debug, Clone, Deftly)]
215
#[derive_deftly(HasMemoryCost)]
216
pub struct ConnectedUdp {
217
    /// The address that the relay has bound locally of a ConnectUdp. Note
218
    /// that this might not be the relay address from the descriptor.
219
    our_address: AddressPort,
220
    /// The address that the stream is connected to.
221
    their_address: AddressPort,
222
}
223

            
224
impl ConnectedUdp {
225
    /// Construct a new ConnectedUdp cell.
226
110
    pub fn new(our_address: AddressPort, their_address: AddressPort) -> Result<Self> {
227
110
        Ok(Self {
228
110
            our_address,
229
110
            their_address,
230
110
        })
231
110
    }
232
}
233

            
234
impl msg::Body for ConnectedUdp {
235
220
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
236
220
        let our_address: AddressPort = r.extract()?;
237
220
        if our_address.addr.is_hostname() {
238
55
            return Err(Error::InvalidMessage("Our address is a Hostname".into()));
239
165
        }
240
165
        let their_address: AddressPort = r.extract()?;
241
165
        if their_address.addr.is_hostname() {
242
55
            return Err(Error::InvalidMessage("Their address is a Hostname".into()));
243
110
        }
244
110

            
245
110
        Ok(Self {
246
110
            our_address,
247
110
            their_address,
248
110
        })
249
220
    }
250

            
251
8
    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
252
8
        w.write(&self.our_address)?;
253
8
        w.write(&self.their_address)?;
254
8
        Ok(())
255
8
    }
256
}
257

            
258
/// A Datagram message represents data sent along a UDP stream.
259
///
260
/// Upon receiving a Datagram message for a live stream, the client or
261
/// exit sends that data onto the associated UDP connection.
262
///
263
/// These messages hold between 1 and [Datagram::MAXLEN] bytes of data each.
264
#[derive(Debug, Clone, Deftly)]
265
#[derive_deftly(HasMemoryCost)]
266
pub struct Datagram {
267
    /// Contents of the cell, to be sent on a specific stream
268
    body: Vec<u8>,
269
}
270

            
271
impl Datagram {
272
    /// NOTE: Proposal 340, fragmented relay message, might change this value reality.
273
    /// The longest allowable body length for a single data cell.
274
    //
275
    // TODO: This length is incorrect for the RelayCellFormat::V1 cell format.
276
    // If/when we return to developing UDP support, we might want to take an approach similar
277
    // to that used in Data cells.
278
    // Alternatively, we might want to remove the maximum entirely
279
    // (if we have implemented prop340 message fragmentation),
280
    // or make this message type only usable along with the V1 format.
281
    pub const MAXLEN: usize = CELL_DATA_LEN - 11;
282

            
283
    /// Construct a new data cell.
284
    ///
285
    /// Returns an error if `inp` is longer than [`Datagram::MAXLEN`] bytes.
286
    pub fn new(inp: &[u8]) -> crate::Result<Self> {
287
        if inp.len() > msg::Data::MAXLEN_V0 {
288
            return Err(crate::Error::CantEncode("Datagram too long"));
289
        }
290
        Ok(Self::new_unchecked(inp.into()))
291
    }
292

            
293
    /// Construct a new cell from a provided vector of bytes.
294
    ///
295
    /// The vector _must_ have fewer than [`Datagram::MAXLEN`] bytes.
296
    fn new_unchecked(body: Vec<u8>) -> Self {
297
        Self { body }
298
    }
299
}
300

            
301
impl From<Datagram> for Vec<u8> {
302
    fn from(data: Datagram) -> Vec<u8> {
303
        data.body
304
    }
305
}
306

            
307
impl AsRef<[u8]> for Datagram {
308
    fn as_ref(&self) -> &[u8] {
309
        &self.body[..]
310
    }
311
}
312

            
313
impl msg::Body for Datagram {
314
    fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
315
        Ok(Datagram {
316
            body: r.take(r.remaining())?.into(),
317
        })
318
    }
319

            
320
    fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
321
        w.write_all(&self.body);
322
        Ok(())
323
    }
324
}