sdlan-lib-rs/src/tcp/tcp_codec.rs

234 lines
4.9 KiB
Rust

use tokio::{
io::{AsyncReadExt, BufReader},
net::tcp::OwnedReadHalf,
};
use num_enum::TryFromPrimitive;
use tracing::debug;
#[derive(Debug)]
pub struct SdlanTcp {
pub _packet_id: u32,
pub packet_type: PacketType,
pub current_packet: Vec<u8>,
}
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
#[repr(u8)]
pub enum EventType {
KnownIP = 0x01,
DropIP = 0x02,
NatChanged = 0x03,
SendRegister = 0x04,
NetworkShutdown = 0xFF,
}
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
#[repr(u8)]
pub enum StunProbeAttr {
None = 0,
Port = 1,
Peer = 2,
}
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
#[repr(u8)]
pub enum NatType {
Blocked = 0,
NoNat = 1,
FullCone = 2,
PortRestricted = 3,
ConeRestricted = 4,
Symmetric = 5,
Invalid = 0xff,
}
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
#[repr(u8)]
pub enum NakMsgCode {
InvalidToken = 1,
NodeDisabled = 2,
NoIpAddress = 3,
NetworkFault = 4,
InternalFault = 5,
}
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
#[repr(u8)]
pub enum PacketType {
Empty = 0x00,
RegisterSuper = 0x01,
RegisterSuperACK = 0x02,
RegisterSuperNAK = 0x04,
UnRegisterSuper = 0x05,
QueryInfo = 0x06,
PeerInfo = 0x07,
Ping = 0x08,
Pong = 0x09,
Event = 0x10,
Command = 0x11,
CommandACK = 0x12,
FlowTracer = 0x15,
Register = 0x20,
RegisterACK = 0x21,
StunRequest = 0x30,
StunReply = 0x31,
StunProbe = 0x32,
StunProbeReply = 0x33,
Data = 0xff,
}
pub async fn read_a_packet(
reader: &mut BufReader<OwnedReadHalf>,
) -> Result<SdlanTcp, std::io::Error> {
debug!("read a packet");
let size = reader.read_u16().await?;
debug!("1");
let packet_id = reader.read_u32().await?;
debug!("2");
let packet_type = reader.read_u8().await?;
debug!("3");
if size < 5 {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"size less than five",
));
}
let bufsize = (size - 5) as usize;
let mut binary = vec![0; bufsize];
let mut to_read = bufsize;
loop {
if to_read == 0 {
break;
}
let size_got = reader.read(&mut binary[(bufsize - to_read)..]).await?;
if size_got == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"read got zero bytes",
));
}
to_read -= size_got;
}
let Ok(packet_type) = packet_type.try_into() else {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"packet type error",
));
};
let result = SdlanTcp {
_packet_id: packet_id,
packet_type,
current_packet: binary,
};
Ok(result)
}
/*
pub async fn read_a_packet2(reader: &mut OwnedReadHalf) -> Result<SdlanTcp, std::io::Error> {
debug!("read a packet");
let size = reader.read_u16().await?;
debug!("1");
let packet_id = reader.read_u32().await?;
debug!("2");
let packet_type = reader.read_u8().await?;
debug!("3");
if size < 5 {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"size less than five",
));
}
let mut binary = vec![0; (size - 5) as usize];
let mut bytes_read = 0;
loop {
let size_got = reader.read(&mut binary[bytes_read..]).await?;
if size_got == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"read got zero bytes",
));
}
bytes_read += size_got;
if bytes_read == (size - 5) as usize {
break;
}
}
let Ok(packet_type) = packet_type.try_into() else {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"packet type error",
));
};
let result = SdlanTcp {
_packet_id: packet_id,
packet_type,
current_packet: binary,
};
Ok(result)
}
impl SdlanTcpCodec {
pub fn new() -> Self {
Self
}
}
#[derive(Debug)]
pub enum Item {
Data(Vec<u8>),
}
impl Decoder for SdlanTcpCodec {
type Item = SdlanTcp;
type Error = std::io::Error;
fn decode(
&mut self,
src: &mut tokio_util::bytes::BytesMut,
) -> Result<Option<Self::Item>, Self::Error> {
if src.is_empty() {
return Ok(None);
}
let size = src.get_u16();
let packet_id = src.get_u32();
let packet_type = src.get_u8();
let mut binary = Vec::with_capacity((size - 5).into());
for i in 0..(size - 5) {
let data = src.get_u8();
binary.push(data);
}
let Ok(packet_type) = packet_type.try_into() else {
return Ok(None);
};
let result = SdlanTcp {
_packet_id: packet_id,
packet_type,
current_packet: binary,
};
Ok(Some(result))
}
}
*/