279 lines
6.3 KiB
Rust
Executable File
279 lines
6.3 KiB
Rust
Executable File
use std::sync::atomic::Ordering;
|
|
|
|
use quinn::RecvStream;
|
|
use tokio::{
|
|
io::{AsyncReadExt},
|
|
};
|
|
|
|
use num_enum::TryFromPrimitive;
|
|
use tracing::{debug, error};
|
|
|
|
use crate::{network::Node, pb::{SdlStunRequest, Sdlv6Info, encode_to_udp_message}, utils::send_to_sock};
|
|
|
|
#[derive(Debug)]
|
|
pub struct SdlanTcp {
|
|
// pub _packet_id: u32,
|
|
pub packet_type: PacketType,
|
|
pub current_packet: Vec<u8>,
|
|
}
|
|
|
|
#[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,
|
|
|
|
Welcome = 0x4f,
|
|
|
|
ArpRequest = 0x50,
|
|
ArpResponse = 0x51,
|
|
|
|
PolicyRequest = 0xb0,
|
|
PolicyReply = 0xb1,
|
|
|
|
Data = 0xff,
|
|
}
|
|
|
|
pub async fn send_stun_request(eee: &Node) {
|
|
let sdl_v6_info = match *eee.ipv6.read().unwrap() {
|
|
Some(ref l) => Some(Sdlv6Info {
|
|
port: l.port as u32,
|
|
v6: Vec::from(l.v6),
|
|
}),
|
|
None => None,
|
|
};
|
|
let req = SdlStunRequest {
|
|
session_token: Vec::from(eee.session_token.get()),
|
|
// cookie: 0,
|
|
client_id: eee.config.node_uuid.clone(),
|
|
network_id: eee.network_id.load(Ordering::Relaxed),
|
|
ip: eee.device_config.get_ip(),
|
|
mac: Vec::from(eee.device_config.get_mac()),
|
|
nat_type: eee.get_nat_type() as u32,
|
|
v6_info: sdl_v6_info,
|
|
};
|
|
debug!("stun request: {:?}", req);
|
|
let msg = encode_to_udp_message(Some(req), PacketType::StunRequest as u8).unwrap();
|
|
if let Err(e) = send_to_sock(
|
|
eee,
|
|
&msg,
|
|
&eee.config.super_nodes[eee.config.super_node_index.load(Ordering::Relaxed) as usize],
|
|
)
|
|
.await
|
|
{
|
|
error!("failed to send to sock: {:?}", e);
|
|
}
|
|
}
|
|
|
|
pub async fn read_a_packet(
|
|
reader: &mut RecvStream,
|
|
) -> Result<SdlanTcp, std::io::Error> {
|
|
// debug!("read a packet");
|
|
let payload_size = reader.read_u16().await?;
|
|
// debug!("payload size: {}", payload_size);
|
|
let packet_type = reader.read_u8().await?;
|
|
// debug!("packet type: 0x{:02x}", packet_type);
|
|
|
|
if payload_size < 1 {
|
|
return Err(std::io::Error::new(
|
|
std::io::ErrorKind::Other,
|
|
"size less than five",
|
|
));
|
|
}
|
|
|
|
let bufsize = (payload_size - 1) 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.is_none() {
|
|
break;
|
|
}
|
|
let size_got = size_got.unwrap();
|
|
|
|
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,
|
|
format!("packet type error: 0x{:02x}", packet_type),
|
|
));
|
|
};
|
|
let result = SdlanTcp {
|
|
// _packet_id: packet_id,
|
|
packet_type,
|
|
current_packet: binary,
|
|
};
|
|
Ok(result)
|
|
}
|
|
|
|
/*
|
|
pub async fn read_a_packet2(reader: &mut OwnedReadHalf) -> Result<SdlanTcp, std::io::Error> {
|
|
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<u8>),
|
|
}
|
|
|
|
impl Decoder for SdlanTcpCodec {
|
|
type Item = SdlanTcp;
|
|
type Error = std::io::Error;
|
|
|
|
fn decode(
|
|
&mut self,
|
|
src: &mut tokio_util::bytes::BytesMut,
|
|
) -> Result<Option<Self::Item>, 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))
|
|
}
|
|
}
|
|
*/
|