1use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
2use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
3use crate::Decode;
4use crate::Encode;
5use crate::{AddressFamily, ErrorCode, StunError};
6
7const ADDRESS_ERROR_CODE: u16 = 0x8001;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct AddressErrorCode {
29 family: AddressFamily,
30 error_code: ErrorCode,
31}
32
33impl AddressErrorCode {
34 pub fn new(family: AddressFamily, error_code: ErrorCode) -> Self {
39 Self { family, error_code }
40 }
41
42 pub fn family(&self) -> AddressFamily {
44 self.family
45 }
46
47 pub fn error_code(&self) -> &ErrorCode {
49 &self.error_code
50 }
51}
52
53impl DecodeAttributeValue for AddressErrorCode {
63 fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
64 let raw_value = ctx.raw_value();
65 let (family, _) = AddressFamily::decode(raw_value)?;
66 let (error_code, size) = ErrorCode::decode(raw_value)?;
67 Ok((AddressErrorCode::new(family, error_code), size))
68 }
69}
70
71impl EncodeAttributeValue for AddressErrorCode {
72 fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
73 let raw_value = ctx.raw_value_mut();
76 let size = self.error_code().encode(raw_value)?;
77 self.family.encode(raw_value)?;
78 Ok(size)
79 }
80}
81
82impl crate::attributes::AsVerifiable for AddressErrorCode {}
83
84stunt_attribute!(AddressErrorCode, ADDRESS_ERROR_CODE);
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use crate::attributes::{DecodeAttributeValue, EncodeAttributeValue};
90 use crate::error::StunErrorType;
91 use crate::StunAttribute;
92
93 #[test]
94 fn decode_address_error_code() {
95 let dummy_msg: [u8; 0] = [0x0; 0];
96 let buffer = [
97 0x01, 0x00, 0x04, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
98 0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
99 0x72, 0x74, 0x65, 0x64,
100 ];
101 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
102 let (attr, size) = AddressErrorCode::decode(ctx).expect("Can not decode AddressErrorCode");
103 assert_eq!(size, 32);
104 assert_eq!(attr.family(), AddressFamily::IPv4);
105 let error = attr.error_code();
106 assert_eq!(error.error_code(), 440);
107 assert_eq!(error.class(), 4);
108 assert_eq!(error.number(), 40);
109 assert_eq!(error.reason(), "Address Family not Supported");
110
111 let buffer = [
112 0x02, 0x00, 0x04, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
113 0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
114 0x72, 0x74, 0x65, 0x64,
115 ];
116 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
117 let (attr, size) = AddressErrorCode::decode(ctx).expect("Can not decode AddressErrorCode");
118 assert_eq!(size, 32);
119 assert_eq!(attr.family(), AddressFamily::IPv6);
120 let error = attr.error_code();
121 assert_eq!(error.error_code(), 440);
122 assert_eq!(error.class(), 4);
123 assert_eq!(error.number(), 40);
124 assert_eq!(error.reason(), "Address Family not Supported");
125 let buffer = [0x01, 0x00, 0x03];
127 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
128 let result = AddressErrorCode::decode(ctx);
129 assert_eq!(
130 result.expect_err("Error expected"),
131 StunErrorType::SmallBuffer
132 );
133
134 let buffer = [
136 0x03, 0x00, 0x04, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
137 0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
138 0x72, 0x74, 0x65, 0x64,
139 ];
140 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
141 let result = AddressErrorCode::decode(ctx);
142 assert_eq!(
143 result.expect_err("Error expected"),
144 StunErrorType::InvalidParam
145 );
146
147 let buffer = [
149 0x02, 0x00, 0x02, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
150 0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
151 0x72, 0x74, 0x65, 0x64,
152 ];
153 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
154 let result = AddressErrorCode::decode(ctx);
155 assert_eq!(
156 result.expect_err("Error expected"),
157 StunErrorType::InvalidParam
158 );
159
160 let buffer = [
162 0x02, 0x00, 0x04, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
163 0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
164 0x72, 0x74, 0x65, 0x64,
165 ];
166 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
167 let result = AddressErrorCode::decode(ctx);
168 assert_eq!(
169 result.expect_err("Error expected"),
170 StunErrorType::InvalidParam
171 );
172 }
173
174 #[test]
175 fn encode_address_error_code() {
176 let dummy_msg: [u8; 0] = [0x0; 0];
177 let error_code =
178 ErrorCode::new(440, "Address Family not Supported").expect("Can not create ErrorCode");
179 let attr = AddressErrorCode::new(AddressFamily::IPv6, error_code);
180
181 let mut buffer: [u8; 31] = [0x0; 31];
182 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
183 let result = attr.encode(ctx);
184 assert_eq!(
185 result.expect_err("Error expected"),
186 StunErrorType::SmallBuffer
187 );
188
189 let mut buffer: [u8; 32] = [0x0; 32];
190 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
191 let result = attr.encode(ctx);
192 assert_eq!(result, Ok(32));
193
194 let expected = [
195 0x02, 0x00, 0x04, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
196 0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
197 0x72, 0x74, 0x65, 0x64,
198 ];
199
200 assert_eq!(&buffer, &expected);
201 }
202
203 #[test]
204 fn address_error_code_stunt_attribute() {
205 let error = ErrorCode::new(533, "test").expect("Can not create error code");
206 let attr =
207 StunAttribute::AddressErrorCode(AddressErrorCode::new(AddressFamily::IPv4, error));
208 assert!(attr.is_address_error_code());
209 assert!(attr.as_address_error_code().is_ok());
210 assert!(attr.as_error_code().is_err());
211
212 assert!(!attr.attribute_type().is_comprehension_required());
213 assert!(attr.attribute_type().is_comprehension_optional());
214
215 let dbg_fmt = format!("{:?}", attr);
216 assert_eq!("AddressErrorCode(AddressErrorCode { family: IPv4, error_code: ErrorCode { error_code: 533, reason: \"test\" } })", dbg_fmt);
217 }
218}