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, } #[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, ) -> Result { 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 { 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), } impl Decoder for SdlanTcpCodec { type Item = SdlanTcp; type Error = std::io::Error; fn decode( &mut self, src: &mut tokio_util::bytes::BytesMut, ) -> Result, 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)) } } */