use crate::{util, StunError};
use std::convert::TryFrom;
#[derive(Debug)]
pub struct ChannelData<'a> {
pub buf: &'a [u8],
pub number: u16,
}
impl ChannelData<'_> {
pub fn message_size(buf: &[u8], is_tcp: bool) -> Result<usize, StunError> {
if !(buf.len() >= 4) {
return Err(StunError::InvalidInput);
}
if !(1..3).contains(&(buf[0] >> 6)) {
return Err(StunError::InvalidInput);
}
let mut size = (util::as_u16(&buf[2..4]) + 4) as usize;
if is_tcp && (size % 4) > 0 {
size += 4 - (size % 4);
}
Ok(size)
}
}
impl<'a> TryFrom<&'a [u8]> for ChannelData<'a> {
type Error = StunError;
fn try_from(buf: &'a [u8]) -> Result<Self, Self::Error> {
if !(buf.len() >= 4) {
return Err(StunError::InvalidInput);
}
let number = util::as_u16(&buf[..2]);
if !(0x4000..0xFFFF).contains(&number) {
return Err(StunError::InvalidInput);
}
let size = util::as_u16(&buf[2..4]) as usize;
if !(size <= buf.len() - 4) {
return Err(StunError::InvalidInput);
}
Ok(Self { buf, number })
}
}
impl AsRef<[u8]> for ChannelData<'_> {
fn as_ref(&self) -> &[u8] {
self.buf
}
}
impl std::ops::Deref for ChannelData<'_> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.buf
}
}