stun_rs/attributes/
unknown.rs1use crate::attributes::{AsVerifiable, EncodeAttributeValue, Verifiable};
2use crate::context::AttributeEncoderContext;
3use crate::error::{StunError, StunErrorType};
4use crate::{AttributeType, StunAttribute};
5use std::sync::Arc;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct Unknown {
15 attr_type: AttributeType,
16 attr_data: Option<Arc<Vec<u8>>>,
17}
18
19impl Unknown {
20 pub(crate) fn new<'a, T>(attr_type: AttributeType, data: T) -> Self
21 where
22 T: Into<Option<&'a [u8]>>,
23 {
24 Self {
25 attr_type,
26 attr_data: data.into().map(Vec::from).map(Arc::new),
27 }
28 }
29
30 pub fn attribute_type(&self) -> AttributeType {
32 self.attr_type
33 }
34
35 pub fn attribute_data(&self) -> Option<&[u8]> {
42 self.attr_data.as_ref().map(|v| v.as_ref().as_slice())
43 }
44}
45
46impl AsVerifiable for Unknown {
47 fn as_verifiable_ref(&self) -> Option<&dyn Verifiable> {
48 None
49 }
50}
51
52impl EncodeAttributeValue for Unknown {
53 fn encode(&self, _ctx: AttributeEncoderContext) -> Result<usize, StunError> {
54 Err(StunError::new(
56 StunErrorType::InvalidParam,
57 format!(
58 "Unknown attribute [{:#02x}] can not be encoded",
59 self.attr_type.as_u16()
60 ),
61 ))
62 }
63
64 fn post_encode(&self, mut _ctx: AttributeEncoderContext) -> Result<(), StunError> {
65 Err(StunError::new(
67 StunErrorType::InvalidParam,
68 format!(
69 "Unknown attribute [{:#02x}] can not be decoded",
70 self.attr_type.as_u16()
71 ),
72 ))
73 }
74}
75
76impl From<Unknown> for StunAttribute {
77 fn from(value: Unknown) -> Self {
78 crate::attributes::StunAttribute::Unknown(value)
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use crate::{DecoderContextBuilder, MessageDecoderBuilder};
86
87 #[test]
88 fn decode_unknown_attribute() {
89 let test_buffer = [
90 0x01, 0x01, 0x00, 0x08, 0x21, 0x12, 0xa4, 0x42, 0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae, 0xff, 0xff, 0x00, 0x02, 0x01, 0x02, 0xff, 0xff,
97 ];
98 let ctx = DecoderContextBuilder::default().build();
99 let decoder = MessageDecoderBuilder::default().with_context(ctx).build();
100
101 let (msg, size) = decoder
102 .decode(&test_buffer)
103 .expect("Can not decode STUN message");
104 assert_eq!(size, 28);
105
106 let attributes = msg.attributes();
107 assert_eq!(attributes.len(), 1);
108
109 let attr = attributes
110 .first()
111 .expect("Can not get first attribute")
112 .as_unknown()
113 .expect("Not unknown attribute");
114 assert_eq!(attr.attribute_type(), AttributeType::from(0xffff));
115 assert_eq!(attr.attribute_data(), None);
116
117 let ctx = DecoderContextBuilder::default().with_unknown_data().build();
119 let decoder = MessageDecoderBuilder::default().with_context(ctx).build();
120 let (msg, size) = decoder
121 .decode(&test_buffer)
122 .expect("Can not decode STUN message");
123 assert_eq!(size, 28);
124
125 let attributes = msg.attributes();
126 assert_eq!(attributes.len(), 1);
127
128 let attr = attributes
129 .first()
130 .expect("Can not get first attribute")
131 .as_unknown()
132 .expect("Not unknown attribute");
133 assert_eq!(attr.attribute_type(), AttributeType::from(0xffff));
134 assert_eq!(attr.attribute_data(), Some([0x01, 0x02].as_ref()));
135
136 assert!(attr.as_verifiable_ref().is_none());
138 }
139
140 #[test]
141 fn encode_unknown_attribute() {
142 let dummy_msg: [u8; 0] = [];
143 let mut buffer: [u8; 6] = [0x00; 6];
144 let attr = Unknown::new(
145 AttributeType::from(0xffff),
146 Some([0x01, 0x02, 0x03, 0x04].as_ref()),
147 );
148
149 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
151 let result = attr.encode(ctx);
152 assert_eq!(
153 result.expect_err("Error expected"),
154 StunErrorType::InvalidParam
155 );
156
157 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
158 let result = attr.post_encode(ctx);
159 assert_eq!(
160 result.expect_err("Error expected"),
161 StunErrorType::InvalidParam
162 );
163 }
164
165 #[test]
166 fn unknown_stunt_attribute() {
167 let attr = StunAttribute::Unknown(Unknown::new(AttributeType::from(0x1234), None));
168 assert!(attr.is_unknown());
169 assert!(attr.as_unknown().is_ok());
170 assert!(attr.as_error_code().is_err());
171
172 let dbg_fmt = format!("{:?}", attr);
173 assert_eq!(
174 "Unknown(Unknown { attr_type: AttributeType (0x1234), attr_data: None })",
175 dbg_fmt
176 );
177 }
178}