stun_rs/attributes/turn/
address_error_code.rs

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/// This attribute is used by servers to signal the reason for not
10/// allocating the requested address family.
11/// # Examples
12///```rust
13/// # use stun_rs::attributes::turn::AddressErrorCode;
14/// # use stun_rs::AddressFamily;
15/// # use std::error::Error;
16/// #
17/// # fn main() -> Result<(), Box<dyn Error>> {
18/// let error = stun_rs::ErrorCode::new(508, "Insufficient Capacity")?;
19/// let attr = AddressErrorCode::new(AddressFamily::IPv4, error);
20/// assert_eq!(attr.error_code().class(), 5);
21/// assert_eq!(attr.error_code().number(), 8);
22/// assert_eq!(attr.error_code().reason(), "Insufficient Capacity");
23/// assert_eq!(attr.family(), AddressFamily::IPv4);
24/// #  Ok(())
25/// # }
26///```
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct AddressErrorCode {
29    family: AddressFamily,
30    error_code: ErrorCode,
31}
32
33impl AddressErrorCode {
34    /// Creates a new [`ErrorCode`] attribute.
35    /// # Arguments:
36    /// * `family` - The address family.
37    /// * `error_code` - The error code.
38    pub fn new(family: AddressFamily, error_code: ErrorCode) -> Self {
39        Self { family, error_code }
40    }
41
42    /// Returns the error code value .
43    pub fn family(&self) -> AddressFamily {
44        self.family
45    }
46
47    /// Returns the error code value .
48    pub fn error_code(&self) -> &ErrorCode {
49        &self.error_code
50    }
51}
52
53// Format of Address-Error-Code Attribute:
54//  0                   1                   2                   3
55//  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
56// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57// |  Family       |    Reserved             |Class|     Number    |
58// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59// |      Reason Phrase (variable)                                ..
60// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
62impl 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's first encode ErrorCode  that will set the first byte (family)
74        // to zero and then encode family
75        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        // short buffer
126        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        // Invalid Ip address family
135        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        // Wrong class: 2
148        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        // Wrong number: 112
161        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}