tor_cell/relaycell/
udp.rs
1use super::msg;
7use crate::chancell::CELL_DATA_LEN;
8use derive_deftly::Deftly;
9use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
10use std::str::FromStr;
11use tor_bytes::{EncodeResult, Error, Result};
12use tor_bytes::{Readable, Reader, Writeable, Writer};
13use tor_memquota::derive_deftly_template_HasMemoryCost;
14
15const T_HOSTNAME: u8 = 0x01;
17const T_IPV4: u8 = 0x04;
19const T_IPV6: u8 = 0x06;
21
22const MAX_HOSTNAME_LEN: usize = u8::MAX as usize;
24
25#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
28#[derive_deftly(HasMemoryCost)]
29pub struct AddressPort {
30 addr: Address,
32 port: u16,
34}
35
36impl Readable for AddressPort {
37 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
38 Ok(Self {
39 addr: r.extract()?,
40 port: r.take_u16()?,
41 })
42 }
43}
44
45impl Writeable for AddressPort {
46 fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
47 w.write(&self.addr)?;
48 w.write_u16(self.port);
49 Ok(())
50 }
51}
52
53impl TryFrom<(&str, u16)> for AddressPort {
54 type Error = Error;
55
56 fn try_from(value: (&str, u16)) -> Result<Self> {
57 let addr = Address::from_str(value.0)?;
58 Ok(Self {
59 addr,
60 port: value.1,
61 })
62 }
63}
64
65#[derive(Clone, Debug, Eq, PartialEq, Deftly)]
67#[derive_deftly(HasMemoryCost)]
68#[non_exhaustive]
69pub enum Address {
70 Hostname(Vec<u8>),
72 Ipv4(Ipv4Addr),
74 Ipv6(Ipv6Addr),
76}
77
78impl Address {
79 pub fn is_hostname(&self) -> bool {
81 matches!(self, Address::Hostname(_))
82 }
83
84 fn wire_addr_type(&self) -> u8 {
86 match self {
87 Address::Hostname(_) => T_HOSTNAME,
88 Address::Ipv4(_) => T_IPV4,
89 Address::Ipv6(_) => T_IPV6,
90 }
91 }
92}
93
94impl Readable for Address {
95 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
96 let addr_type = r.take_u8()?;
97 r.read_nested_u8len(|r| {
98 Ok(match addr_type {
99 T_HOSTNAME => {
100 let h = r.take_rest();
101 Self::Hostname(h.into())
102 }
103 T_IPV4 => Self::Ipv4(r.extract()?),
104 T_IPV6 => Self::Ipv6(r.extract()?),
105 _ => return Err(Error::InvalidMessage("Invalid address type".into())),
106 })
107 })
108 }
109}
110
111impl Writeable for Address {
112 fn write_onto<B: Writer + ?Sized>(&self, w: &mut B) -> EncodeResult<()> {
113 w.write_u8(self.wire_addr_type());
115 let mut w = w.write_nested_u8len();
117
118 match self {
119 Address::Hostname(h) => {
120 w.write_all(&h[..]);
121 }
122 Address::Ipv4(ip) => w.write(ip)?,
123 Address::Ipv6(ip) => w.write(ip)?,
124 }
125
126 w.finish()
127 }
128}
129
130impl FromStr for Address {
131 type Err = Error;
132
133 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
134 if let Ok(ipv4) = Ipv4Addr::from_str(s) {
135 Ok(Self::Ipv4(ipv4))
136 } else if let Ok(ipv6) = Ipv6Addr::from_str(s) {
137 Ok(Self::Ipv6(ipv6))
138 } else {
139 if s.len() > MAX_HOSTNAME_LEN {
140 return Err(Error::InvalidMessage("Hostname too long".into()));
141 }
142 if s.contains('\0') {
143 return Err(Error::InvalidMessage("Nul byte not permitted".into()));
144 }
145
146 let mut addr = s.to_string();
147 addr.make_ascii_lowercase();
148 Ok(Self::Hostname(addr.into_bytes()))
149 }
150 }
151}
152
153impl 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#[derive(Debug, Clone, Deftly)]
172#[derive_deftly(HasMemoryCost)]
173pub struct ConnectUdp {
174 flags: msg::BeginFlags,
176 addr: AddressPort,
178}
179
180impl ConnectUdp {
181 pub fn new<F>(addr: &str, port: u16, flags: F) -> crate::Result<Self>
183 where
184 F: Into<msg::BeginFlags>,
185 {
186 Ok(Self {
187 addr: (addr, port)
188 .try_into()
189 .map_err(|_| crate::Error::BadStreamAddress)?,
190 flags: flags.into(),
191 })
192 }
193}
194
195impl msg::Body for ConnectUdp {
196 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
197 let flags = r.take_u32()?;
198 let addr = r.extract()?;
199
200 Ok(Self {
201 flags: flags.into(),
202 addr,
203 })
204 }
205
206 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
207 w.write_u32(self.flags.bits());
208 w.write(&self.addr)?;
209 Ok(())
210 }
211}
212
213#[derive(Debug, Clone, Deftly)]
215#[derive_deftly(HasMemoryCost)]
216pub struct ConnectedUdp {
217 our_address: AddressPort,
220 their_address: AddressPort,
222}
223
224impl ConnectedUdp {
225 pub fn new(our_address: AddressPort, their_address: AddressPort) -> Result<Self> {
227 Ok(Self {
228 our_address,
229 their_address,
230 })
231 }
232}
233
234impl msg::Body for ConnectedUdp {
235 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
236 let our_address: AddressPort = r.extract()?;
237 if our_address.addr.is_hostname() {
238 return Err(Error::InvalidMessage("Our address is a Hostname".into()));
239 }
240 let their_address: AddressPort = r.extract()?;
241 if their_address.addr.is_hostname() {
242 return Err(Error::InvalidMessage("Their address is a Hostname".into()));
243 }
244
245 Ok(Self {
246 our_address,
247 their_address,
248 })
249 }
250
251 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
252 w.write(&self.our_address)?;
253 w.write(&self.their_address)?;
254 Ok(())
255 }
256}
257
258#[derive(Debug, Clone, Deftly)]
265#[derive_deftly(HasMemoryCost)]
266pub struct Datagram {
267 body: Vec<u8>,
269}
270
271impl Datagram {
272 pub const MAXLEN: usize = CELL_DATA_LEN - 11;
282
283 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 fn new_unchecked(body: Vec<u8>) -> Self {
297 Self { body }
298 }
299}
300
301impl From<Datagram> for Vec<u8> {
302 fn from(data: Datagram) -> Vec<u8> {
303 data.body
304 }
305}
306
307impl AsRef<[u8]> for Datagram {
308 fn as_ref(&self) -> &[u8] {
309 &self.body[..]
310 }
311}
312
313impl 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}