msf_stun/
attribute.rs

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
34/// Attribute error.
35pub enum AttributeError {
36    InvalidAttribute,
37    UnknownAttribute(u16),
38}
39
40/// Attribute header.
41struct AttributeHeader {
42    attribute_type: u16,
43    attribute_length: u16,
44}
45
46impl AttributeHeader {
47    /// Consumer attribute header from a given buffer and parse it.
48    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    /// Get length of the attribute value.
62    fn value_length(&self) -> usize {
63        self.attribute_length as usize
64    }
65
66    /// Get length of the attribute value including padding.
67    fn padded_value_length(&self) -> usize {
68        (self.attribute_length as usize + 3) & !3
69    }
70}
71
72/// STUN message attribute.
73#[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    /// Consume the next attribute from a given buffer.
102    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    /// Parse mapped address.
154    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    /// Parse XOR mapped address.
184    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    /// Parse username.
225    fn username_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
226        Self::string_from_bytes(value).map(Self::Username)
227    }
228
229    /// Parse message integrity.
230    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    /// Parse fingerprint.
245    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    /// Parse error code.
256    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    /// Parse realm.
276    fn realm_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
277        Self::string_from_bytes(value).map(Self::Realm)
278    }
279
280    /// Parse nonce.
281    fn nonce_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
282        Self::string_from_bytes(value).map(Self::Nonce)
283    }
284
285    /// Parse unknown attributes.
286    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    /// Parse software.
301    fn software_from_bytes(value: &mut Bytes) -> Result<Self, AttributeError> {
302        Self::string_from_bytes(value).map(Self::Software)
303    }
304
305    /// Parse alternate server.
306    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    /// Parse priority.
314    #[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    /// Parse use candidate.
324    #[cfg(feature = "ice")]
325    fn use_candidate_from_bytes(_: &mut Bytes) -> Result<Self, AttributeError> {
326        Ok(Self::UseCandidate)
327    }
328
329    /// Parse ICE controlled.
330    #[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    /// Parse ICE controlling.
340    #[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    /// Parse a string.
350    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/// Collection of attributes.
362#[derive(Clone)]
363pub struct Attributes {
364    inner: Vec<Attribute>,
365}
366
367impl Attributes {
368    /// Create an empty collection of attributes.
369    pub(crate) const fn empty() -> Self {
370        Self::new(Vec::new())
371    }
372
373    /// Create a new collection of attributes.
374    pub(crate) const fn new(attributes: Vec<Attribute>) -> Self {
375        Self { inner: attributes }
376    }
377
378    /// Get the error code attribute.
379    #[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    /// Get the unknown attributes attribute.
388    #[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    /// Get the alternate server attribute.
397    #[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    /// Get the mapped address attribute.
406    #[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    /// Get the XOR mapped address attribute.
415    #[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    /// Get either the XOR mapped address attribute or the mapped address
424    /// attribute if the XOR mapped attribute does not exist.
425    #[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    /// Get the username attribute.
435    #[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    /// Get the realm attribute.
444    #[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    /// Get the nonce attribute.
453    #[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    /// Get the software attribute.
462    #[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    /// Get ICE candidate priority.
471    #[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    /// Get the use ICE candidate attribute.
481    #[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    /// Get the ICE controlled attribute.
490    #[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    /// Get the ICE controlling attribute.
500    #[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}