use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
use crate::Decode;
use crate::Encode;
use crate::{AddressFamily, ErrorCode, StunError};
const ADDRESS_ERROR_CODE: u16 = 0x8001;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AddressErrorCode {
family: AddressFamily,
error_code: ErrorCode,
}
impl AddressErrorCode {
pub fn new(family: AddressFamily, error_code: ErrorCode) -> Self {
Self { family, error_code }
}
pub fn family(&self) -> AddressFamily {
self.family
}
pub fn error_code(&self) -> &ErrorCode {
&self.error_code
}
}
impl DecodeAttributeValue for AddressErrorCode {
fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
let raw_value = ctx.raw_value();
let (family, _) = AddressFamily::decode(raw_value)?;
let (error_code, size) = ErrorCode::decode(raw_value)?;
Ok((AddressErrorCode::new(family, error_code), size))
}
}
impl EncodeAttributeValue for AddressErrorCode {
fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
let raw_value = ctx.raw_value_mut();
let size = self.error_code().encode(raw_value)?;
self.family.encode(raw_value)?;
Ok(size)
}
}
impl crate::attributes::AsVerifiable for AddressErrorCode {}
stunt_attribute!(AddressErrorCode, ADDRESS_ERROR_CODE);
#[cfg(test)]
mod tests {
use super::*;
use crate::attributes::{DecodeAttributeValue, EncodeAttributeValue};
use crate::error::StunErrorType;
use crate::StunAttribute;
#[test]
fn decode_address_error_code() {
let dummy_msg: [u8; 0] = [0x0; 0];
let buffer = [
0x01, 0x00, 0x04, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
0x72, 0x74, 0x65, 0x64,
];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let (attr, size) = AddressErrorCode::decode(ctx).expect("Can not decode AddressErrorCode");
assert_eq!(size, 32);
assert_eq!(attr.family(), AddressFamily::IPv4);
let error = attr.error_code();
assert_eq!(error.error_code(), 440);
assert_eq!(error.class(), 4);
assert_eq!(error.number(), 40);
assert_eq!(error.reason(), "Address Family not Supported");
let buffer = [
0x02, 0x00, 0x04, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
0x72, 0x74, 0x65, 0x64,
];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let (attr, size) = AddressErrorCode::decode(ctx).expect("Can not decode AddressErrorCode");
assert_eq!(size, 32);
assert_eq!(attr.family(), AddressFamily::IPv6);
let error = attr.error_code();
assert_eq!(error.error_code(), 440);
assert_eq!(error.class(), 4);
assert_eq!(error.number(), 40);
assert_eq!(error.reason(), "Address Family not Supported");
let buffer = [0x01, 0x00, 0x03];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let result = AddressErrorCode::decode(ctx);
assert_eq!(
result.expect_err("Error expected"),
StunErrorType::SmallBuffer
);
let buffer = [
0x03, 0x00, 0x04, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
0x72, 0x74, 0x65, 0x64,
];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let result = AddressErrorCode::decode(ctx);
assert_eq!(
result.expect_err("Error expected"),
StunErrorType::InvalidParam
);
let buffer = [
0x02, 0x00, 0x02, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
0x72, 0x74, 0x65, 0x64,
];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let result = AddressErrorCode::decode(ctx);
assert_eq!(
result.expect_err("Error expected"),
StunErrorType::InvalidParam
);
let buffer = [
0x02, 0x00, 0x04, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
0x72, 0x74, 0x65, 0x64,
];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let result = AddressErrorCode::decode(ctx);
assert_eq!(
result.expect_err("Error expected"),
StunErrorType::InvalidParam
);
}
#[test]
fn encode_address_error_code() {
let dummy_msg: [u8; 0] = [0x0; 0];
let error_code =
ErrorCode::new(440, "Address Family not Supported").expect("Can not create ErrorCode");
let attr = AddressErrorCode::new(AddressFamily::IPv6, error_code);
let mut buffer: [u8; 31] = [0x0; 31];
let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
let result = attr.encode(ctx);
assert_eq!(
result.expect_err("Error expected"),
StunErrorType::SmallBuffer
);
let mut buffer: [u8; 32] = [0x0; 32];
let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
let result = attr.encode(ctx);
assert_eq!(result, Ok(32));
let expected = [
0x02, 0x00, 0x04, 0x28, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x46, 0x61,
0x6D, 0x69, 0x6C, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6F,
0x72, 0x74, 0x65, 0x64,
];
assert_eq!(&buffer, &expected);
}
#[test]
fn address_error_code_stunt_attribute() {
let error = ErrorCode::new(533, "test").expect("Can not create error code");
let attr =
StunAttribute::AddressErrorCode(AddressErrorCode::new(AddressFamily::IPv4, error));
assert!(attr.is_address_error_code());
assert!(attr.as_address_error_code().is_ok());
assert!(attr.as_error_code().is_err());
assert!(!attr.attribute_type().is_comprehension_required());
assert!(attr.attribute_type().is_comprehension_optional());
let dbg_fmt = format!("{:?}", attr);
assert_eq!("AddressErrorCode(AddressErrorCode { family: IPv4, error_code: ErrorCode { error_code: 533, reason: \"test\" } })", dbg_fmt);
}
}