chagned the packet marshal and unmarshal

This commit is contained in:
asxalex 2024-02-27 15:02:10 +08:00
parent b7adef51e8
commit a81f7cd8f9
4 changed files with 231 additions and 13 deletions

View File

@ -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<T: serde::Serialize>(
Ok(result)
}
pub fn encode_packet_packet(cmn: &Common, pkt: &Packet<'_>) -> Result<Vec<u8>> {
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<T: serde::Serialize>(cmn: &Common, pkt: &T) -> Result<Vec<u8>> {
// header
let hdr = cmn.encode();

View File

@ -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<SdlanSock>,
pub v6_info: Option<V6Info>,
pub data: &'a [u8],
}
pub data: Vec<u8>,
impl<'a> Packet<'a> {
pub fn unmarshal(data: &'a [u8], has_sock: bool, has_v6: bool) -> Result<Self> {
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<Vec<u8>> {
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(())
}
}

View File

@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use crate::peer::{IpSubnet, SdlanSock};
use crate::peer::SdlanSock;
#[derive(Serialize, Deserialize)]
pub struct Register {

View File

@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
use crate::peer::SdlanSock;
#[derive(Serialize, Deserialize)]
pub struct RegisterACK {
pub cookie: u32,
// 返回方的tun接口的ip地址