stun_rs/attributes/turn/
requested_transport.rsuse crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
use crate::common::check_buffer_boundaries;
use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
use crate::protocols::{ProtocolNumber, UDP};
use crate::{Decode, Encode, StunError};
const REQUESTED_TRANSPORT: u16 = 0x0019;
const REQUESTED_TRANSPORT_SIZE: usize = 4;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RequestedTrasport(ProtocolNumber);
impl RequestedTrasport {
pub fn new(protocol: ProtocolNumber) -> Self {
Self(protocol)
}
pub fn protocol(&self) -> ProtocolNumber {
self.0
}
}
impl From<ProtocolNumber> for RequestedTrasport {
fn from(value: ProtocolNumber) -> Self {
RequestedTrasport(value)
}
}
impl Default for RequestedTrasport {
fn default() -> Self {
RequestedTrasport(UDP)
}
}
impl DecodeAttributeValue for RequestedTrasport {
fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
let raw_value = ctx.raw_value();
check_buffer_boundaries(raw_value, REQUESTED_TRANSPORT_SIZE)?;
Ok((
Self(ProtocolNumber::decode(raw_value)?.0),
REQUESTED_TRANSPORT_SIZE,
))
}
}
impl EncodeAttributeValue for RequestedTrasport {
fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
let raw_value = ctx.raw_value_mut();
check_buffer_boundaries(raw_value, REQUESTED_TRANSPORT_SIZE)?;
let size = self.0.encode(raw_value)?;
debug_assert!(
size == 1,
"Unexpected size of type `ProtocolNumber`, {} != 1",
size
);
raw_value[size..REQUESTED_TRANSPORT_SIZE].fill(0x0);
Ok(REQUESTED_TRANSPORT_SIZE)
}
}
impl crate::attributes::AsVerifiable for RequestedTrasport {}
stunt_attribute!(RequestedTrasport, REQUESTED_TRANSPORT);
#[cfg(test)]
mod tests {
use super::*;
use crate::error::StunErrorType;
use crate::protocols;
use crate::StunAttribute;
#[test]
fn decode_requested_transport_constructor() {
let attr = RequestedTrasport::new(protocols::UDP);
assert_eq!(attr.protocol(), protocols::UDP);
let attr = RequestedTrasport::from(protocols::UDP);
assert_eq!(attr.protocol(), protocols::UDP);
}
#[test]
fn decode_requested_transport_value() {
let dummy_msg = [];
let buffer = [];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let result = RequestedTrasport::decode(ctx);
assert_eq!(
result.expect_err("Error expected"),
StunErrorType::SmallBuffer
);
let buffer = [0x11, 0x00, 0x00];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let result = RequestedTrasport::decode(ctx);
assert_eq!(
result.expect_err("Error expected"),
StunErrorType::SmallBuffer
);
let buffer = [0x11, 0x00, 0x00, 0x00];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let (attr, size) =
RequestedTrasport::decode(ctx).expect("Can not decode RequestedTrasport");
assert_eq!(size, 4);
assert_eq!(attr.protocol(), protocols::UDP);
let buffer = [0x06, 0x01, 0x02, 0x03];
let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
let (attr, size) =
RequestedTrasport::decode(ctx).expect("Can not decode RequestedTrasport");
assert_eq!(size, 4);
assert_eq!(attr.protocol().as_u8(), 6);
}
#[test]
fn encode_requested_transport_value() {
let attr = RequestedTrasport::default();
let dummy_msg = [];
let mut buffer = [];
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; 3] = [0xFF; 3];
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; 4] = [0xFF; 4];
let attr = RequestedTrasport::new(protocols::UDP);
let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
let result = attr.encode(ctx);
assert_eq!(result, Ok(4));
let expected_buffer = [0x11, 0x00, 0x00, 0x00];
assert_eq!(&buffer[..], &expected_buffer[..]);
}
#[test]
fn requested_transport_stunt_attribute() {
let attr = StunAttribute::RequestedTrasport(RequestedTrasport::from(protocols::UDP));
assert!(attr.is_requested_trasport());
assert!(attr.as_requested_trasport().is_ok());
assert!(attr.as_unknown().is_err());
assert!(attr.attribute_type().is_comprehension_required());
assert!(!attr.attribute_type().is_comprehension_optional());
let dbg_fmt = format!("{:?}", attr);
assert_eq!(
"RequestedTrasport(RequestedTrasport(ProtocolNumber(17)))",
dbg_fmt
);
}
}