stun_rs/attributes/stun/
unknown_attributes.rs

1use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
2use crate::common::check_buffer_boundaries;
3use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
4use crate::error::{StunError, StunErrorType};
5use byteorder::{BigEndian, ByteOrder};
6use std::convert::From;
7use std::ops::Deref;
8use std::sync::Arc;
9
10const UNKNOWN_ATTRIBUTES: u16 = 0x000A;
11
12// Format of Unknown-Attribute:
13//  0                   1                   2                   3
14//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
15//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16//  |      Attribute 1 Type         |       Attribute 2 Type        |
17//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18//  |      Attribute 3 Type         |       Attribute 4 Type    ...
19//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20
21/// The [`UnknownAttributes`] is present only in an error response
22/// when the response code in the ERROR-CODE attribute is 420 (Unknown Attribute).
23///
24/// # Examples
25///```rust
26/// # use stun_rs::attributes::stun::UnknownAttributes;
27/// // Creates an empty unknown attributes
28/// let mut attr = UnknownAttributes::default();
29/// assert_eq!(attr.iter().count(), 0);
30///
31/// // Add an unknown attribute
32/// attr.add(2134);
33/// assert_eq!(attr.iter().count(), 1);
34///```
35#[derive(Debug, Clone, PartialEq, Eq, Default)]
36pub struct UnknownAttributes {
37    attrs: Arc<Vec<u16>>,
38}
39
40impl UnknownAttributes {
41    /// Adds a new unknown attribute
42    /// # Arguments:
43    /// - 'value' - Attribute type
44    pub fn add(&mut self, value: u16) {
45        if !self.attrs.contains(&value) {
46            Arc::make_mut(&mut self.attrs).push(value);
47        }
48    }
49
50    /// Return the array of unknown attributes
51    pub fn attributes(&self) -> &[u16] {
52        self.attrs.as_slice()
53    }
54
55    /// Returns an iterator over the unknown attributes.
56    pub fn iter(&self) -> impl Iterator<Item = &u16> {
57        self.attrs.iter()
58    }
59}
60
61impl Deref for UnknownAttributes {
62    type Target = [u16];
63
64    fn deref(&self) -> &[u16] {
65        &self.attrs
66    }
67}
68
69impl From<&[u16]> for UnknownAttributes {
70    fn from(v: &[u16]) -> Self {
71        let mut attr = UnknownAttributes::default();
72        v.iter().for_each(|x| attr.add(*x));
73        attr
74    }
75}
76
77impl DecodeAttributeValue for UnknownAttributes {
78    fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
79        let mut unknown_attr = UnknownAttributes::default();
80
81        let raw_value = ctx.raw_value();
82
83        if raw_value.len() & 1 != 0 {
84            // This is not a list of 16-bit values
85            return Err(StunError::new(
86                StunErrorType::SmallBuffer,
87                format!(
88                    "Buffer of size ({}) does not contain a list of 16-bits values",
89                    raw_value.len()
90                ),
91            ));
92        }
93
94        for i in 0..raw_value.len() / 2 {
95            unknown_attr.add(BigEndian::read_u16(&raw_value[i * 2..]));
96        }
97
98        Ok((unknown_attr, raw_value.len()))
99    }
100}
101
102impl EncodeAttributeValue for UnknownAttributes {
103    fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
104        let len = self.attrs.len() * 2;
105        let raw_value = ctx.raw_value_mut();
106        check_buffer_boundaries(raw_value, len)?;
107
108        self.attrs.iter().enumerate().for_each(|(i, x)| {
109            BigEndian::write_u16(&mut raw_value[i * 2..], *x);
110        });
111
112        Ok(len)
113    }
114}
115
116impl crate::attributes::AsVerifiable for UnknownAttributes {}
117
118stunt_attribute!(UnknownAttributes, UNKNOWN_ATTRIBUTES);
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123    use crate::error::StunErrorType;
124    use crate::StunAttribute;
125
126    #[test]
127    fn constructor() {
128        let mut attrs = vec![4, 2, 3];
129        let attr = UnknownAttributes::from(attrs.as_slice());
130
131        assert_eq!(attr.attributes().len(), attrs.len());
132        assert_eq!(attr.attributes(), attrs.as_slice());
133
134        // Check deref
135        let slice: &[u16] = &attr;
136        assert_eq!(slice, attrs.as_slice());
137
138        // Check duplicated are discarded
139        attrs.push(4);
140        attrs.push(3);
141        attrs.push(2);
142        let attr = UnknownAttributes::from(attrs.as_slice());
143
144        assert_eq!(attr.attributes().len(), 3);
145    }
146
147    #[test]
148    fn add_type() {
149        let mut attr = UnknownAttributes::default();
150        assert_eq!(attr.attributes().len(), 0);
151
152        attr.add(3);
153        assert_eq!(attr.attributes().len(), 1);
154
155        attr.add(5);
156        assert_eq!(attr.attributes().len(), 2);
157
158        // Check duplicated are discarded
159        attr.add(3);
160        assert_eq!(attr.attributes().len(), 2);
161        attr.add(5);
162        assert_eq!(attr.attributes().len(), 2);
163    }
164
165    #[test]
166    fn decode_unknown_attributes() {
167        let dummy_msg = [];
168        let buffer = [0x00, 0x02, 0x00, 0x6, 0x01, 0x41, 0x0A, 0x00];
169        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
170        let (attr, size) = UnknownAttributes::decode(ctx).expect("Can not get UNKNOWN-ATTRIBUTES");
171        assert_eq!(size, 8);
172        let attrs = attr.attributes();
173
174        assert!(attrs.contains(&2));
175        assert!(attrs.contains(&6));
176        assert!(attrs.contains(&321));
177        assert!(attrs.contains(&2560));
178    }
179
180    #[test]
181    fn decode_unknown_attributes_fail() {
182        let dummy_msg = [];
183        // short buffer
184        let buffer = [0x00];
185        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
186        let result = UnknownAttributes::decode(ctx);
187        assert_eq!(
188            result.expect_err("Error expected"),
189            StunErrorType::SmallBuffer
190        );
191
192        // Last attribute type number is not a valid u16 (2 bytes in size), 1 byte missed
193        let buffer = [0x00, 0x02, 0x0B];
194        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
195        let result = UnknownAttributes::decode(ctx);
196        assert_eq!(
197            result.expect_err("Error expected"),
198            StunErrorType::SmallBuffer
199        );
200    }
201
202    #[test]
203    fn encode_unknown_attributes() {
204        let attrs = vec![4, 2, 3];
205        let attr = UnknownAttributes::from(attrs.as_slice());
206        let dummy_msg: [u8; 0] = [0x0; 0];
207
208        let mut buffer: [u8; 6] = [0x0; 6];
209        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
210        let result = attr.encode(ctx);
211        assert_eq!(result, Ok(6));
212
213        let cmp_buffer = [0x00, 0x04, 0x00, 0x02, 0x00, 0x03];
214        assert_eq!(&buffer[..], &cmp_buffer[..]);
215    }
216
217    #[test]
218    fn encode_unknown_attributes_fail() {
219        let attrs = vec![4, 2, 3];
220        let attr = UnknownAttributes::from(attrs.as_slice());
221        let dummy_msg: [u8; 0] = [0x0; 0];
222
223        // Small buffer
224        let mut buffer: [u8; 5] = [0x0; 5];
225        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
226        let result = attr.encode(ctx);
227        assert_eq!(
228            result.expect_err("Error expected"),
229            StunErrorType::SmallBuffer
230        );
231    }
232
233    #[test]
234    fn unknown_attributes_stunt_attribute() {
235        let attr = StunAttribute::UnknownAttributes(UnknownAttributes::default());
236        assert!(attr.is_unknown_attributes());
237        assert!(attr.as_unknown_attributes().is_ok());
238        assert!(attr.as_unknown().is_err());
239
240        assert!(attr.attribute_type().is_comprehension_required());
241        assert!(!attr.attribute_type().is_comprehension_optional());
242
243        let dbg_fmt = format!("{:?}", attr);
244        assert_eq!(
245            "UnknownAttributes(UnknownAttributes { attrs: [] })",
246            dbg_fmt
247        );
248    }
249}