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 crate::utils::Result;
use super::packet::Packet;
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
use serde_repr::*; use serde_repr::*;
@ -182,6 +183,24 @@ pub fn encode_packet_encrypted<T: serde::Serialize>(
Ok(result) 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>> { pub fn encode_packet<T: serde::Serialize>(cmn: &Common, pkt: &T) -> Result<Vec<u8>> {
// header // header
let hdr = cmn.encode(); let hdr = cmn.encode();

View File

@ -1,17 +1,118 @@
use crate::peer::SdlanSock; use crate::{
use serde::{Deserialize, Serialize}; config,
peer::{SdlanSock, V6Info},
utils::{Result, SDLanError},
};
// use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)] // #[derive(Serialize, Deserialize)]
pub struct Packet { pub struct Packet<'a> {
pub src_ip: u32, pub src_ip: u32,
pub dst_ip: u32, pub dst_ip: u32,
pub sock: Option<SdlanSock>, 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)] #[cfg(test)]
mod test { mod test {
use crate::config;
use crate::peer::V6Info;
use crate::utils::Result; use crate::utils::Result;
use crate::{config::AF_INET, packet::*, peer::SdlanSock, utils::gen_uuid}; use crate::{config::AF_INET, packet::*, peer::SdlanSock, utils::gen_uuid};
@ -20,25 +121,32 @@ mod test {
let id = gen_uuid(); let id = gen_uuid();
let data = gen_uuid(); let data = gen_uuid();
let cmn1 = Common::new(&id); let cmn1 = Common::new(&id);
let packet = Packet { let mut packet = Packet {
src_ip: 1, src_ip: 1,
dst_ip: 2, dst_ip: 2,
sock: None,
/*
sock: Some(SdlanSock { sock: Some(SdlanSock {
family: AF_INET, family: AF_INET,
port: 80, port: 80,
v4: [1; 4], v4: [1; 4],
v6: [1; 16], v6: [1; 16],
}), }),
data: data.into_bytes(), */
v6_info: None,
data: data.as_bytes(),
// data: &data.into_bytes(), // data: &data.into_bytes(),
}; };
let info = encode_packet(&cmn1, &packet)?; let info = encode_packet_packet(&cmn1, &packet)?;
let (cmn2, rest) = decode_common(&info)?; let (cmn2, rest) = decode_common(&info)?;
if cmn2.id != cmn1.id { if cmn2.id != cmn1.id {
panic!("cmn not equal"); panic!("cmn not equal");
} }
let packet2 = Packet::unmarshal(rest, false, false)?;
/*
let data_str = std::str::from_utf8(rest); let data_str = std::str::from_utf8(rest);
if let Err(e) = data_str { if let Err(e) = data_str {
panic!("convert data failed: {}", e); panic!("convert data failed: {}", e);
@ -46,11 +154,10 @@ mod test {
let data_str = data_str.unwrap(); let data_str = data_str.unwrap();
println!("got packet data: {}", data_str); 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!(packet.data, packet2.data);
assert_eq!(packet2.v6_info, None);
assert_eq!(packet2.sock, None);
/* /*
match packet2.data { match packet2.data {
Cow::Borrowed(d) => { 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(()) Ok(())
} }
} }

View File

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

View File

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