From a81f7cd8f96e6783fec03dbb0abfd17571d3586c Mon Sep 17 00:00:00 2001 From: asxalex Date: Tue, 27 Feb 2024 15:02:10 +0800 Subject: [PATCH] chagned the packet marshal and unmarshal --- src/packet/common.rs | 19 ++++ src/packet/packet.rs | 222 +++++++++++++++++++++++++++++++++++-- src/packet/register.rs | 2 +- src/packet/register_ack.rs | 1 + 4 files changed, 231 insertions(+), 13 deletions(-) diff --git a/src/packet/common.rs b/src/packet/common.rs index f3cba28..27bbfd8 100644 --- a/src/packet/common.rs +++ b/src/packet/common.rs @@ -1,5 +1,6 @@ use crate::utils::Result; +use super::packet::Packet; use byteorder::{BigEndian, ByteOrder}; use serde_repr::*; @@ -182,6 +183,24 @@ pub fn encode_packet_encrypted( Ok(result) } +pub fn encode_packet_packet(cmn: &Common, pkt: &Packet<'_>) -> Result> { + let hdr = cmn.encode(); + let body = pkt.marshal()?; + + let mut result = Vec::with_capacity(4 + hdr.len() + body.len()); + let total_size = (2 + hdr.len() + body.len()) as u16; + // insert total size + result.extend_from_slice(&total_size.to_be_bytes()); + // packet_id + result.extend_from_slice(&[0, 0]); + // insert header + result.extend_from_slice(&hdr); + // insert body + result.extend_from_slice(&body); + + Ok(result) +} + pub fn encode_packet(cmn: &Common, pkt: &T) -> Result> { // header let hdr = cmn.encode(); diff --git a/src/packet/packet.rs b/src/packet/packet.rs index b509a41..24d5908 100644 --- a/src/packet/packet.rs +++ b/src/packet/packet.rs @@ -1,17 +1,118 @@ -use crate::peer::SdlanSock; -use serde::{Deserialize, Serialize}; +use crate::{ + config, + peer::{SdlanSock, V6Info}, + utils::{Result, SDLanError}, +}; +// use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize)] -pub struct Packet { +// #[derive(Serialize, Deserialize)] +pub struct Packet<'a> { pub src_ip: u32, pub dst_ip: u32, pub sock: Option, + pub v6_info: Option, + pub data: &'a [u8], +} - pub data: Vec, +impl<'a> Packet<'a> { + pub fn unmarshal(data: &'a [u8], has_sock: bool, has_v6: bool) -> Result { + let mut tmp = data; + if data.len() < 8 { + return Err(SDLanError::NormalError("packet header data len error")); + } + let src_ip = u32::from_be_bytes(tmp[0..4].try_into().unwrap()); + let dst_ip = u32::from_be_bytes(tmp[4..8].try_into().unwrap()); + tmp = &tmp[8..]; + let mut sock = None; + if has_sock { + if tmp.len() < 7 { + return Err(SDLanError::NormalError("packet socket data len error")); + } + let family = tmp[0]; + let tempu8 = [tmp[1], tmp[2]]; + let port = u16::from_be_bytes(tempu8); + let mut tmpsock = SdlanSock { + family, + port, + v4: [0; 4], + v6: [0; 16], + }; + match family { + config::AF_INET6 => { + if tmp.len() < 19 { + return Err(SDLanError::NormalError("packet socket v6 len error")); + } + // size is guaranteed + tmpsock.v6 = tmp[3..19].try_into().unwrap(); + tmp = &tmp[19..] + } + config::AF_INET => { + // size is guaranteed + tmpsock.v4 = tmp[3..7].try_into().unwrap(); + tmp = &tmp[7..] + } + other => { + return Err(SDLanError::NormalError("packet socket family error")); + } + } + sock = Some(tmpsock); + } + let mut v6_info = None; + if has_v6 { + if tmp.len() < 18 { + return Err(SDLanError::NormalError("packet v6_info len error")); + } + v6_info = Some(V6Info { + port: u16::from_be_bytes(tmp[0..2].try_into().unwrap()), + v6: tmp[2..18].try_into().unwrap(), + }); + tmp = &tmp[18..]; + } + + Ok(Packet { + src_ip, + dst_ip, + sock, + v6_info, + data: tmp, + }) + } + + pub fn marshal(&self) -> Result> { + let mut result = Vec::new(); + result.extend_from_slice(&self.src_ip.to_be_bytes()); + result.extend_from_slice(&self.dst_ip.to_be_bytes()); + if let Some(ref v) = self.sock { + result.push(v.family); + result.extend_from_slice(&v.port.to_be_bytes()); + match v.family { + config::AF_INET => { + result.extend_from_slice(&v.v4); + } + config::AF_INET6 => { + result.extend_from_slice(&v.v6); + } + _other => { + return Err(SDLanError::NormalError( + "marshal packet error: unknown family", + )); + } // _other=> return Err(SDLanError::NormalError("marshal packet error: unknown family")); + } + } + if let Some(ref v) = self.v6_info { + result.extend_from_slice(&v.port.to_be_bytes()); + result.extend_from_slice(&v.v6); + } + result.extend_from_slice(&self.data); + + Ok(result) + } } #[cfg(test)] mod test { + use crate::config; + use crate::peer::V6Info; use crate::utils::Result; use crate::{config::AF_INET, packet::*, peer::SdlanSock, utils::gen_uuid}; @@ -20,25 +121,32 @@ mod test { let id = gen_uuid(); let data = gen_uuid(); let cmn1 = Common::new(&id); - let packet = Packet { + let mut packet = Packet { src_ip: 1, dst_ip: 2, + sock: None, + /* sock: Some(SdlanSock { family: AF_INET, port: 80, v4: [1; 4], v6: [1; 16], }), - data: data.into_bytes(), + */ + v6_info: None, + data: data.as_bytes(), // data: &data.into_bytes(), }; - let info = encode_packet(&cmn1, &packet)?; + let info = encode_packet_packet(&cmn1, &packet)?; let (cmn2, rest) = decode_common(&info)?; if cmn2.id != cmn1.id { panic!("cmn not equal"); } + + let packet2 = Packet::unmarshal(rest, false, false)?; + /* let data_str = std::str::from_utf8(rest); if let Err(e) = data_str { panic!("convert data failed: {}", e); @@ -46,11 +154,10 @@ mod test { let data_str = data_str.unwrap(); println!("got packet data: {}", data_str); } - let packet2: Packet = match serde_json::from_slice(rest) { - Ok(p) => p, - Err(e) => panic!("failed to unmarshal: {}", e), - }; + */ assert_eq!(packet.data, packet2.data); + assert_eq!(packet2.v6_info, None); + assert_eq!(packet2.sock, None); /* match packet2.data { Cow::Borrowed(d) => { @@ -61,6 +168,97 @@ mod test { } } */ + packet.sock = Some(SdlanSock { + family: config::AF_INET, + port: 12, + v4: [1; 4], + v6: [1; 16], + }); + + let info = encode_packet_packet(&cmn1, &packet)?; + + let (cmn2, rest) = decode_common(&info)?; + if cmn2.id != cmn1.id { + panic!("cmn not equal"); + } + + let packet3 = Packet::unmarshal(rest, true, false)?; + match packet3.sock { + None => panic!("packet3, sock None"), + Some(ref sk) => { + assert_eq!(sk.family, config::AF_INET); + assert_eq!(sk.port, 12); + assert_eq!(sk.v4, [1; 4]); + assert_eq!(sk.v6, [0; 16]); + } + } + assert_eq!(packet3.v6_info, None); + assert_eq!(packet.data, packet3.data); + + packet.v6_info = Some(V6Info { + port: 24, + v6: [2; 16], + }); + + let info = encode_packet_packet(&cmn1, &packet)?; + + let (cmn2, rest) = decode_common(&info)?; + if cmn2.id != cmn1.id { + panic!("cmn not equal"); + } + + let packet4 = Packet::unmarshal(rest, true, true)?; + match packet4.sock { + None => panic!("packet3, sock None"), + Some(ref sk) => { + assert_eq!(sk.family, config::AF_INET); + assert_eq!(sk.port, 12); + assert_eq!(sk.v4, [1; 4]); + assert_eq!(sk.v6, [0; 16]); + } + } + match packet4.v6_info { + None => panic!("packet4, v6_info None"), + Some(ref v6) => { + assert_eq!(v6.port, 24); + assert_eq!(v6.v6, [2; 16]); + } + } + assert_eq!(packet.data, packet4.data); + + packet.sock = Some(SdlanSock { + family: config::AF_INET6, + port: 24, + v4: [1; 4], + v6: [2; 16], + }); + + let info = encode_packet_packet(&cmn1, &packet)?; + + let (cmn2, rest) = decode_common(&info)?; + if cmn2.id != cmn1.id { + panic!("cmn not equal"); + } + + let packet5 = Packet::unmarshal(rest, true, true)?; + match packet5.sock { + None => panic!("packet3, sock None"), + Some(ref sk) => { + assert_eq!(sk.family, config::AF_INET6); + assert_eq!(sk.port, 24); + assert_eq!(sk.v4, [0; 4]); + assert_eq!(sk.v6, [2; 16]); + } + } + match packet5.v6_info { + None => panic!("packet4, v6_info None"), + Some(ref v6) => { + assert_eq!(v6.port, 24); + assert_eq!(v6.v6, [2; 16]); + } + } + assert_eq!(packet.data, packet5.data); + Ok(()) } } diff --git a/src/packet/register.rs b/src/packet/register.rs index 1be5a6f..5eef7d1 100644 --- a/src/packet/register.rs +++ b/src/packet/register.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -use crate::peer::{IpSubnet, SdlanSock}; +use crate::peer::SdlanSock; #[derive(Serialize, Deserialize)] pub struct Register { diff --git a/src/packet/register_ack.rs b/src/packet/register_ack.rs index 9b8769b..2b03042 100644 --- a/src/packet/register_ack.rs +++ b/src/packet/register_ack.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::peer::SdlanSock; +#[derive(Serialize, Deserialize)] pub struct RegisterACK { pub cookie: u32, // 返回方的tun接口的ip地址