stun_rs/attributes/stun/
unknown_attributes.rs1use 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#[derive(Debug, Clone, PartialEq, Eq, Default)]
36pub struct UnknownAttributes {
37 attrs: Arc<Vec<u16>>,
38}
39
40impl UnknownAttributes {
41 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 pub fn attributes(&self) -> &[u16] {
52 self.attrs.as_slice()
53 }
54
55 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 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 let slice: &[u16] = &attr;
136 assert_eq!(slice, attrs.as_slice());
137
138 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 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 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 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 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}