1use std::{
2 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
3 ops::Deref,
4};
5
6use bytes::{Buf, Bytes};
7
8use crate::ErrorCode;
9
10pub const ATTR_TYPE_MAPPED_ADDRESS: u16 = 0x0001;
11pub const ATTR_TYPE_XOR_MAPPED_ADDRESS: u16 = 0x0020;
12pub const ATTR_TYPE_USERNAME: u16 = 0x0006;
13pub const ATTR_TYPE_MESSAGE_INTEGRITY: u16 = 0x0008;
14pub const ATTR_TYPE_FINGERPRINT: u16 = 0x8028;
15pub const ATTR_TYPE_ERROR_CODE: u16 = 0x0009;
16pub const ATTR_TYPE_REALM: u16 = 0x0014;
17pub const ATTR_TYPE_NONCE: u16 = 0x0015;
18pub const ATTR_TYPE_UNKNOWN_ATTRIBUTES: u16 = 0x000A;
19pub const ATTR_TYPE_SOFTWARE: u16 = 0x8022;
20pub const ATTR_TYPE_ALTERNATE_SERVER: u16 = 0x8023;
21
22#[cfg(feature = "ice")]
23pub const ATTR_TYPE_PRIORITY: u16 = 0x0024;
24
25#[cfg(feature = "ice")]
26pub const ATTR_TYPE_USE_CANDIDATE: u16 = 0x0025;
27
28#[cfg(feature = "ice")]
29pub const ATTR_TYPE_ICE_CONTROLLED: u16 = 0x8029;
30
31#[cfg(feature = "ice")]
32pub const ATTR_TYPE_ICE_CONTROLLING: u16 = 0x802A;
33
34pub enum AttributeError {
36 InvalidAttribute,
37 UnknownAttribute(u16),
38}
39
40struct AttributeHeader {
42 attribute_type: u16,
43 attribute_length: u16,
44}
45
46impl AttributeHeader {
47 fn from_bytes(data: &mut Bytes) -> Result<Self, AttributeError> {
49 if data.len() < 4 {
50 return Err(AttributeError::InvalidAttribute);
51 }
52
53 let res = Self {
54 attribute_type: data.get_u16(),
55 attribute_length: data.get_u16(),
56 };
57
58 Ok(res)
59 }
60
61 fn value_length(&self) -> usize {
63 self.attribute_length as usize
64 }
65
66 fn padded_value_length(&self) -> usize {
68 (self.attribute_length as usize + 3) & !3
69 }
70}
71
72#[derive(Clone)]
74pub enum Attribute {
75 MappedAddress(SocketAddr),
76 XorMappedAddress(SocketAddr),
77 Username(String),
78 MessageIntegrity([u8; 20]),
79 Fingerprint(u32),
80 ErrorCode(ErrorCode),
81 Realm(String),
82 Nonce(String),
83 UnknownAttributes(Vec<u16>),
84 Software(String),
85 AlternateServer(SocketAddr),
86
87 #[cfg(feature = "ice")]
88 Priority(u32),
89
90 #[cfg(feature = "ice")]
91 UseCandidate,
92
93 #[cfg(feature = "ice")]
94 ICEControlled(u64),
95
96 #[cfg(feature = "ice")]
97 ICEControlling(u64),
98}
99
100impl Attribute {
101 pub fn from_bytes(
103 data: &mut Bytes,
104 long_transaction_id: [u8; 16],
105 ) -> Result<Self, AttributeError> {
106 let header = AttributeHeader::from_bytes(data)?;
107
108 if data.len() < header.padded_value_length() {
109 return Err(AttributeError::InvalidAttribute);
110 }
111
112 let mut value = data.slice(..header.value_length());
113
114 data.advance(header.padded_value_length());
115
116 let res = match header.attribute_type {
117 ATTR_TYPE_MAPPED_ADDRESS => Self::mapped_address_from_bytes(&mut value)?,
118 ATTR_TYPE_XOR_MAPPED_ADDRESS => {
119 Self::xor_mapped_address_from_bytes(&mut value, long_transaction_id)?
120 }
121 ATTR_TYPE_USERNAME => Self::username_from_bytes(&mut value)?,
122 ATTR_TYPE_MESSAGE_INTEGRITY => Self::message_integrity_from_bytes(&mut value)?,
123 ATTR_TYPE_FINGERPRINT => Self::fingerprint_from_bytes(&mut value)?,
124 ATTR_TYPE_ERROR_CODE => Self::error_code_from_bytes(&mut value)?,
125 ATTR_TYPE_REALM => Self::realm_from_bytes(&mut value)?,
126 ATTR_TYPE_NONCE => Self::nonce_from_bytes(&mut value)?,
127 ATTR_TYPE_UNKNOWN_ATTRIBUTES => Self::unknown_attributes_from_bytes(&mut value)?,
128 ATTR_TYPE_SOFTWARE => Self::software_from_bytes(&mut value)?,
129 ATTR_TYPE_ALTERNATE_SERVER => Self::alternate_server_from_bytes(&mut value)?,
130
131 #[cfg(feature = "ice")]
132 ATTR_TYPE_PRIORITY => Self::priority_from_bytes(&mut value)?,
133
134 #[cfg(feature = "ice")]
135 ATTR_TYPE_USE_CANDIDATE => Self::use_candidate_from_bytes(&mut value)?,
136
137 #[cfg(feature = "ice")]
138 ATTR_TYPE_ICE_CONTROLLED => Self::ice_controlled_from_bytes(&mut value)?,
139
140 #[cfg(feature = "ice")]
141 ATTR_TYPE_ICE_CONTROLLING => Self::ice_controlling_from_bytes(&mut value)?,
142
143 t => return Err(AttributeError::UnknownAttribute(t)),
144 };
145
146 if !value.is_empty() {
147 return Err(AttributeError::InvalidAttribute);
148 }
149
150 Ok(res)
151 }
152
153 fn mapped_address_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
155 if value.len() < 4 {
156 return Err(AttributeError::InvalidAttribute);
157 }
158
159 value.advance(1);
160
161 let family = value.get_u8();
162 let port = value.get_u16();
163
164 let expected = match family {
165 1 => 4,
166 2 => 16,
167 _ => return Err(AttributeError::InvalidAttribute),
168 };
169
170 if value.len() < expected {
171 return Err(AttributeError::InvalidAttribute);
172 }
173
174 let addr = match family {
175 1 => IpAddr::from(Ipv4Addr::from(value.get_u32())),
176 2 => IpAddr::from(Ipv6Addr::from(value.get_u128())),
177 _ => unreachable!(),
178 };
179
180 Ok(Self::MappedAddress(SocketAddr::from((addr, port))))
181 }
182
183 fn xor_mapped_address_from_bytes(
185 value: &mut Bytes,
186 long_transaction_id: [u8; 16],
187 ) -> Result<Self, AttributeError> {
188 if value.len() < 4 {
189 return Err(AttributeError::InvalidAttribute);
190 }
191
192 value.advance(1);
193
194 let mut magic_cookie = [0u8; 4];
195
196 magic_cookie.copy_from_slice(&long_transaction_id[..4]);
197
198 let u128_xor_bits = u128::from_be_bytes(long_transaction_id);
199 let u32_xor_bits = u32::from_be_bytes(magic_cookie);
200 let u16_xor_bits = (u32_xor_bits >> 16) as u16;
201
202 let family = value.get_u8();
203 let port = value.get_u16() ^ u16_xor_bits;
204
205 let expected = match family {
206 1 => 4,
207 2 => 16,
208 _ => return Err(AttributeError::InvalidAttribute),
209 };
210
211 if value.len() < expected {
212 return Err(AttributeError::InvalidAttribute);
213 }
214
215 let addr = match family {
216 1 => IpAddr::from(Ipv4Addr::from(value.get_u32() ^ u32_xor_bits)),
217 2 => IpAddr::from(Ipv6Addr::from(value.get_u128() ^ u128_xor_bits)),
218 _ => unreachable!(),
219 };
220
221 Ok(Self::XorMappedAddress(SocketAddr::from((addr, port))))
222 }
223
224 fn username_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
226 Self::string_from_bytes(value).map(Self::Username)
227 }
228
229 fn message_integrity_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
231 if value.len() < 20 {
232 return Err(AttributeError::InvalidAttribute);
233 }
234
235 let mut hash = [0u8; 20];
236
237 hash.copy_from_slice(&value[..20]);
238
239 value.advance(20);
240
241 Ok(Self::MessageIntegrity(hash))
242 }
243
244 fn fingerprint_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
246 if value.len() < 4 {
247 return Err(AttributeError::InvalidAttribute);
248 }
249
250 let crc = value.get_u32();
251
252 Ok(Self::Fingerprint(crc))
253 }
254
255 fn error_code_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
257 if value.len() < 4 {
258 return Err(AttributeError::InvalidAttribute);
259 }
260
261 value.advance(2);
262
263 let class = (value.get_u8() & 7) as u16;
264 let num = value.get_u8() as u16;
265
266 if num > 99 {
267 return Err(AttributeError::InvalidAttribute);
268 }
269
270 let msg = Self::string_from_bytes(value)?;
271
272 Ok(Self::ErrorCode(ErrorCode::new(class * 100 + num, msg)))
273 }
274
275 fn realm_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
277 Self::string_from_bytes(value).map(Self::Realm)
278 }
279
280 fn nonce_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
282 Self::string_from_bytes(value).map(Self::Nonce)
283 }
284
285 fn unknown_attributes_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
287 if (value.len() & 1) != 0 {
288 return Err(AttributeError::InvalidAttribute);
289 }
290
291 let mut res = Vec::with_capacity(value.len() >> 1);
292
293 while !value.is_empty() {
294 res.push(value.get_u16());
295 }
296
297 Ok(Self::UnknownAttributes(res))
298 }
299
300 fn software_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
302 Self::string_from_bytes(value).map(Self::Software)
303 }
304
305 fn alternate_server_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
307 match Self::mapped_address_from_bytes(value)? {
308 Self::MappedAddress(addr) => Ok(Self::AlternateServer(addr)),
309 _ => unreachable!(),
310 }
311 }
312
313 #[cfg(feature = "ice")]
315 fn priority_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
316 if value.len() < 4 {
317 return Err(AttributeError::InvalidAttribute);
318 }
319
320 Ok(Self::Priority(value.get_u32()))
321 }
322
323 #[cfg(feature = "ice")]
325 fn use_candidate_from_bytes(_: &mut Bytes) -> Result<Self, AttributeError> {
326 Ok(Self::UseCandidate)
327 }
328
329 #[cfg(feature = "ice")]
331 fn ice_controlled_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
332 if value.len() < 8 {
333 return Err(AttributeError::InvalidAttribute);
334 }
335
336 Ok(Self::ICEControlled(value.get_u64()))
337 }
338
339 #[cfg(feature = "ice")]
341 fn ice_controlling_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
342 if value.len() < 8 {
343 return Err(AttributeError::InvalidAttribute);
344 }
345
346 Ok(Self::ICEControlling(value.get_u64()))
347 }
348
349 fn string_from_bytes(value: &mut Bytes) -> Result<String, AttributeError> {
351 let res = std::str::from_utf8(value)
352 .map(|s| s.to_string())
353 .map_err(|_| AttributeError::InvalidAttribute)?;
354
355 value.clear();
356
357 Ok(res)
358 }
359}
360
361#[derive(Clone)]
363pub struct Attributes {
364 inner: Vec<Attribute>,
365}
366
367impl Attributes {
368 pub(crate) const fn empty() -> Self {
370 Self::new(Vec::new())
371 }
372
373 pub(crate) const fn new(attributes: Vec<Attribute>) -> Self {
375 Self { inner: attributes }
376 }
377
378 #[inline]
380 pub fn get_error_code(&self) -> Option<&ErrorCode> {
381 self.inner.iter().find_map(|attr| match attr {
382 Attribute::ErrorCode(status) => Some(status),
383 _ => None,
384 })
385 }
386
387 #[inline]
389 pub fn get_unknown_attributes(&self) -> Option<&[u16]> {
390 self.inner.iter().find_map(|attr| match attr {
391 Attribute::UnknownAttributes(attrs) => Some(attrs.as_ref()),
392 _ => None,
393 })
394 }
395
396 #[inline]
398 pub fn get_alternate_server(&self) -> Option<SocketAddr> {
399 self.inner.iter().find_map(|attr| match attr {
400 Attribute::AlternateServer(addr) => Some(*addr),
401 _ => None,
402 })
403 }
404
405 #[inline]
407 pub fn get_mapped_address(&self) -> Option<SocketAddr> {
408 self.inner.iter().find_map(|attr| match attr {
409 Attribute::MappedAddress(addr) => Some(*addr),
410 _ => None,
411 })
412 }
413
414 #[inline]
416 pub fn get_xor_mapped_address(&self) -> Option<SocketAddr> {
417 self.inner.iter().find_map(|attr| match attr {
418 Attribute::XorMappedAddress(addr) => Some(*addr),
419 _ => None,
420 })
421 }
422
423 #[inline]
426 pub fn get_any_mapped_address(&self) -> Option<SocketAddr> {
427 if let Some(addr) = self.get_xor_mapped_address() {
428 Some(addr)
429 } else {
430 self.get_mapped_address()
431 }
432 }
433
434 #[inline]
436 pub fn get_username(&self) -> Option<&str> {
437 self.inner.iter().find_map(|attr| match attr {
438 Attribute::Username(username) => Some(username.as_str()),
439 _ => None,
440 })
441 }
442
443 #[inline]
445 pub fn get_realm(&self) -> Option<&str> {
446 self.inner.iter().find_map(|attr| match attr {
447 Attribute::Realm(realm) => Some(realm.as_str()),
448 _ => None,
449 })
450 }
451
452 #[inline]
454 pub fn get_nonce(&self) -> Option<&str> {
455 self.inner.iter().find_map(|attr| match attr {
456 Attribute::Nonce(nonce) => Some(nonce.as_str()),
457 _ => None,
458 })
459 }
460
461 #[inline]
463 pub fn get_software(&self) -> Option<&str> {
464 self.inner.iter().find_map(|attr| match attr {
465 Attribute::Software(software) => Some(software.as_str()),
466 _ => None,
467 })
468 }
469
470 #[cfg(feature = "ice")]
472 #[inline]
473 pub fn get_priority(&self) -> Option<u32> {
474 self.inner.iter().find_map(|attr| match attr {
475 Attribute::Priority(n) => Some(*n),
476 _ => None,
477 })
478 }
479
480 #[cfg(feature = "ice")]
482 #[inline]
483 pub fn get_use_candidate(&self) -> bool {
484 self.inner
485 .iter()
486 .any(|attr| matches!(attr, Attribute::UseCandidate))
487 }
488
489 #[cfg(feature = "ice")]
491 #[inline]
492 pub fn get_ice_controlled(&self) -> Option<u64> {
493 self.inner.iter().find_map(|attr| match attr {
494 Attribute::ICEControlled(n) => Some(*n),
495 _ => None,
496 })
497 }
498
499 #[cfg(feature = "ice")]
501 #[inline]
502 pub fn get_ice_controlling(&self) -> Option<u64> {
503 self.inner.iter().find_map(|attr| match attr {
504 Attribute::ICEControlling(n) => Some(*n),
505 _ => None,
506 })
507 }
508}
509
510impl Deref for Attributes {
511 type Target = [Attribute];
512
513 #[inline]
514 fn deref(&self) -> &Self::Target {
515 &self.inner
516 }
517}