chagned the packet marshal and unmarshal
This commit is contained in:
parent
b7adef51e8
commit
a81f7cd8f9
@ -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();
|
||||||
|
|||||||
@ -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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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地址
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user