fix all error
This commit is contained in:
parent
375a0671f8
commit
56d6a35fea
402
Cargo.lock
generated
402
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -16,8 +16,9 @@ message SDLV6Info {
|
||||
// 设备网络地址信息
|
||||
message SDLDevAddr {
|
||||
uint32 network_id = 1;
|
||||
uint32 net_addr = 2;
|
||||
uint32 net_bit_len = 3;
|
||||
bytes mac = 2;
|
||||
uint32 net_addr = 3;
|
||||
uint32 net_bit_len = 4;
|
||||
}
|
||||
|
||||
// tcp通讯消息
|
||||
@ -37,7 +38,7 @@ message SDLRegisterSuper {
|
||||
message SDLRegisterSuperAck {
|
||||
SDLDevAddr dev_addr = 1;
|
||||
bytes aes_key = 2;
|
||||
bytes known_ips = 3;
|
||||
map<uint32, bytes> known_macs = 3;
|
||||
uint32 upgrade_type = 4;
|
||||
optional string upgrade_prompt = 5;
|
||||
optional string upgrade_address = 6;
|
||||
@ -51,31 +52,34 @@ message SDLRegisterSuperNak {
|
||||
// 网络地址查询
|
||||
|
||||
message SDLQueryInfo {
|
||||
uint32 dst_ip = 1;
|
||||
bytes dst_mac = 1;
|
||||
}
|
||||
|
||||
message SDLPeerInfo {
|
||||
uint32 dst_ip = 1;
|
||||
bytes dst_mac = 1;
|
||||
SDLV4Info v4_info = 2;
|
||||
optional SDLV6Info v6_info = 3;
|
||||
}
|
||||
|
||||
// 事件定义
|
||||
|
||||
message SDLKnownIpEvent {
|
||||
uint32 ip = 1;
|
||||
message SDLKnownMacEvent {
|
||||
bytes mac = 1;
|
||||
uint32 ip = 2;
|
||||
}
|
||||
|
||||
message SDLDropIpEvent {
|
||||
uint32 ip = 1;
|
||||
message SDLDropMacEvent {
|
||||
bytes mac = 1;
|
||||
uint32 ip = 2;
|
||||
}
|
||||
|
||||
message SDLNatChangedEvent {
|
||||
uint32 ip = 1;
|
||||
bytes mac = 1;
|
||||
uint32 ip = 2;
|
||||
}
|
||||
|
||||
message SDLSendRegisterEvent {
|
||||
uint32 dst_ip = 1;
|
||||
bytes dst_mac = 1;
|
||||
uint32 nat_ip = 2;
|
||||
uint32 nat_port = 3;
|
||||
optional SDLV6Info v6_info = 4;
|
||||
@ -90,7 +94,7 @@ message SDLNetworkShutdownEvent {
|
||||
message SDLChangeNetworkCommand {
|
||||
SDLDevAddr dev_addr = 1;
|
||||
bytes aes_key = 2;
|
||||
bytes known_ips = 3;
|
||||
map<uint32, bytes> known_macs = 3;
|
||||
}
|
||||
|
||||
message SDLCommandAck {
|
||||
@ -114,9 +118,10 @@ message SDLStunRequest {
|
||||
uint32 cookie = 1;
|
||||
string client_id = 2;
|
||||
uint32 network_id = 3;
|
||||
uint32 ip = 4;
|
||||
uint32 nat_type = 5;
|
||||
optional SDLV6Info v6_info = 6;
|
||||
bytes mac = 4;
|
||||
uint32 ip = 5;
|
||||
uint32 nat_type = 6;
|
||||
optional SDLV6Info v6_info = 7;
|
||||
}
|
||||
|
||||
message SDLStunReply {
|
||||
@ -125,8 +130,8 @@ message SDLStunReply {
|
||||
|
||||
message SDLData {
|
||||
uint32 network_id = 1;
|
||||
uint32 src_ip = 2;
|
||||
uint32 dst_ip = 3;
|
||||
bytes src_mac = 2;
|
||||
bytes dst_mac = 3;
|
||||
bool is_p2p = 4;
|
||||
uint32 ttl = 5;
|
||||
bytes data = 6;
|
||||
@ -134,14 +139,14 @@ message SDLData {
|
||||
|
||||
message SDLRegister {
|
||||
uint32 network_id = 1;
|
||||
uint32 src_ip = 2;
|
||||
uint32 dst_ip = 3;
|
||||
bytes src_mac = 2;
|
||||
bytes dst_mac = 3;
|
||||
}
|
||||
|
||||
message SDLRegisterAck {
|
||||
uint32 network_id = 1;
|
||||
uint32 src_ip = 2;
|
||||
uint32 dst_ip = 3;
|
||||
bytes src_mac = 2;
|
||||
bytes dst_mac = 3;
|
||||
}
|
||||
|
||||
// 网络类型探测
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use sdlan_sn_rs::utils::Mac;
|
||||
|
||||
pub const REGISTER_INTERVAL: u8 = 20;
|
||||
pub const REGISTER_SUPER_INTERVAL: u16 = 20;
|
||||
|
||||
@ -7,3 +9,5 @@ pub const MULTICAST_PORT: u16 = 1970;
|
||||
// pub const SUPER_ATTEMPTS_DEFAULT: u8 = 3;
|
||||
|
||||
pub const TCP_PING_TIME: u64 = 7;
|
||||
|
||||
pub const NULL_MAC: Mac = [0, 0, 0, 0, 0, 0];
|
||||
|
||||
15
src/lib.rs
15
src/lib.rs
@ -9,12 +9,12 @@ use std::{sync::atomic::AtomicU8, time::Duration};
|
||||
use std::net::{SocketAddr, ToSocketAddrs};
|
||||
|
||||
pub use network::get_edge;
|
||||
use network::{async_main, init_edge, NodeConfig};
|
||||
pub use network::get_install_channel;
|
||||
use network::{async_main, init_arp, init_edge, NodeConfig};
|
||||
use tokio::sync::mpsc::{channel, Sender};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{debug, error};
|
||||
pub use utils::{CommandLine, CommandLineInput};
|
||||
pub use network::get_install_channel;
|
||||
|
||||
use sdlan_sn_rs::{
|
||||
peer::SdlanSock,
|
||||
@ -34,14 +34,15 @@ pub async fn run_sdlan(
|
||||
sender: std::sync::mpsc::Sender<bool>,
|
||||
install_channel: &str,
|
||||
|
||||
connecting_chan: Option<Sender<ConnectionState>>
|
||||
// start_stop_sender: Sender<String>,
|
||||
// start_stop_receiver: Receiver<String>,
|
||||
connecting_chan: Option<Sender<ConnectionState>>, // start_stop_sender: Sender<String>,
|
||||
// start_stop_receiver: Receiver<String>,
|
||||
) -> Result<()> {
|
||||
let (start_stop_sender, start_stop_chan) = channel(20);
|
||||
let edge_uuid = create_or_load_uuid("")?;
|
||||
let node_conf = parse_config(edge_uuid, &args).await?;
|
||||
|
||||
init_arp();
|
||||
|
||||
if let Err(e) = init_edge(&args.token, node_conf, args.tos, start_stop_sender).await {
|
||||
panic!("failed to init edge: {:?}", e);
|
||||
}
|
||||
@ -51,7 +52,9 @@ pub async fn run_sdlan(
|
||||
let cancel = CancellationToken::new();
|
||||
let install_chan = install_channel.to_owned();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = async_main(install_chan, args, start_stop_chan, cancel, connecting_chan).await {
|
||||
if let Err(e) =
|
||||
async_main(install_chan, args, start_stop_chan, cancel, connecting_chan).await
|
||||
{
|
||||
error!("failed to run async main: {}", e.as_str());
|
||||
}
|
||||
});
|
||||
|
||||
367
src/network/arp.rs
Normal file
367
src/network/arp.rs
Normal file
@ -0,0 +1,367 @@
|
||||
use std::{
|
||||
array,
|
||||
sync::atomic::{AtomicU8, Ordering},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use tracing::error;
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use sdlan_sn_rs::utils::{net_bit_len_to_mask, Mac, BROADCAST_MAC, MULTICAST_MAC};
|
||||
use tokio::sync::{
|
||||
mpsc::{channel, Receiver, Sender},
|
||||
oneshot,
|
||||
};
|
||||
|
||||
use super::{get_edge, get_route_table};
|
||||
|
||||
static GLOBAL_ARP: OnceCell<ArpActor> = OnceCell::new();
|
||||
pub fn init_arp() {
|
||||
let actor = ArpActor::new();
|
||||
GLOBAL_ARP.set(actor).unwrap();
|
||||
}
|
||||
|
||||
pub fn get_arp() -> &'static ArpActor {
|
||||
GLOBAL_ARP.get().unwrap()
|
||||
}
|
||||
|
||||
const ETHER_TYPE_ARP: u16 = 0x0806;
|
||||
const ETHER_TYPE_IP: u16 = 0x0800;
|
||||
const ETHER_TYPE_IP6: u16 = 0x86dd;
|
||||
|
||||
const ARP_MAX_AGE: u8 = 128;
|
||||
|
||||
const ARP_HWTYPE_ETH: u16 = 1;
|
||||
|
||||
pub const ARP_REQUEST: u16 = 1;
|
||||
pub const ARP_REPLY: u16 = 2;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EthHdr {
|
||||
pub dest: [u8; 6],
|
||||
pub src: [u8; 6],
|
||||
pub eth_type: u16,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ArpHdr {
|
||||
pub ethhdr: EthHdr,
|
||||
pub hwtype: u16,
|
||||
pub protocol: u16,
|
||||
pub hwlen: u8,
|
||||
pub protolen: u8,
|
||||
pub opcode: u16,
|
||||
pub shwaddr: [u8; 6],
|
||||
pub sipaddr: [u16; 2],
|
||||
pub dhwaddr: [u8; 6],
|
||||
pub dipaddr: [u16; 2],
|
||||
}
|
||||
|
||||
impl ArpHdr {
|
||||
pub fn from_slice(data: &[u8]) -> Self {
|
||||
if data.len() < 42 {
|
||||
panic!("data size error");
|
||||
}
|
||||
Self {
|
||||
ethhdr: EthHdr {
|
||||
dest: data[0..6].try_into().unwrap(),
|
||||
src: data[6..12].try_into().unwrap(),
|
||||
eth_type: u16::from_be_bytes(data[12..14].try_into().unwrap()),
|
||||
},
|
||||
hwtype: u16::from_be_bytes(data[14..16].try_into().unwrap()),
|
||||
protocol: u16::from_be_bytes(data[16..18].try_into().unwrap()),
|
||||
hwlen: data[18],
|
||||
protolen: data[19],
|
||||
opcode: u16::from_be_bytes(data[20..22].try_into().unwrap()),
|
||||
shwaddr: data[22..28].try_into().unwrap(),
|
||||
sipaddr: [
|
||||
u16::from_be_bytes(data[28..30].try_into().unwrap()),
|
||||
u16::from_be_bytes(data[30..32].try_into().unwrap()),
|
||||
],
|
||||
dhwaddr: data[32..38].try_into().unwrap(),
|
||||
dipaddr: [
|
||||
u16::from_be_bytes(data[38..40].try_into().unwrap()),
|
||||
u16::from_be_bytes(data[40..42].try_into().unwrap()),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn marshal_to_bytes(&self) -> Vec<u8> {
|
||||
let mut result = Vec::with_capacity(42);
|
||||
result.extend_from_slice(&self.ethhdr.dest);
|
||||
result.extend_from_slice(&self.ethhdr.src);
|
||||
result.extend_from_slice(&self.ethhdr.eth_type.to_be_bytes());
|
||||
result.extend_from_slice(&self.hwtype.to_be_bytes());
|
||||
result.extend_from_slice(&self.protocol.to_be_bytes());
|
||||
result.push(self.hwlen);
|
||||
result.push(self.protolen);
|
||||
result.extend_from_slice(&self.opcode.to_be_bytes());
|
||||
result.extend_from_slice(&self.shwaddr);
|
||||
result.extend_from_slice(&self.sipaddr[0].to_be_bytes());
|
||||
result.extend_from_slice(&self.sipaddr[1].to_be_bytes());
|
||||
|
||||
result.extend_from_slice(&self.dhwaddr);
|
||||
result.extend_from_slice(&self.dipaddr[0].to_be_bytes());
|
||||
result.extend_from_slice(&self.dipaddr[1].to_be_bytes());
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ethhdr: EthHdr {
|
||||
dest: [0; 6],
|
||||
src: [0; 6],
|
||||
eth_type: ETHER_TYPE_ARP,
|
||||
},
|
||||
hwtype: ARP_HWTYPE_ETH,
|
||||
protocol: ETHER_TYPE_IP,
|
||||
hwlen: 6,
|
||||
protolen: 4,
|
||||
opcode: ARP_REQUEST,
|
||||
shwaddr: [0; 6],
|
||||
sipaddr: [0; 2],
|
||||
dhwaddr: [0; 6],
|
||||
dipaddr: [0; 2],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ARP_TABLE_SIZE: usize = 8;
|
||||
static ARPTIME: AtomicU8 = AtomicU8::new(0);
|
||||
const BROADCAST_IPADDR: u32 = 0xffffffff;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArpEntry {
|
||||
ip_addr: u32,
|
||||
arptime: u8,
|
||||
hw_addr: [u8; 6],
|
||||
}
|
||||
|
||||
impl ArpEntry {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ip_addr: 0,
|
||||
arptime: 0,
|
||||
hw_addr: [0; 6],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ArpInfo {
|
||||
// host_ip: AtomicU32,
|
||||
// ip representation of mask
|
||||
// host_netmask: AtomicU32,
|
||||
entry: [ArpEntry; ARP_TABLE_SIZE],
|
||||
}
|
||||
|
||||
impl ArpInfo {
|
||||
fn lookup_ip_mac(&self, ip: u32) -> ([u8; 6], u32, bool) {
|
||||
if ip == BROADCAST_IPADDR {
|
||||
return (BROADCAST_MAC, ip, false);
|
||||
}
|
||||
let first_ip = (ip >> 24) as u8 & 0xff;
|
||||
if first_ip >= 224 && first_ip <= 239 {
|
||||
return (MULTICAST_MAC, ip, false);
|
||||
}
|
||||
let mut target_ip = 0;
|
||||
let edge = get_edge();
|
||||
|
||||
let host_ip = edge.device_config.get_ip();
|
||||
let host_netmask = net_bit_len_to_mask(edge.device_config.get_net_bit());
|
||||
|
||||
if (ip & host_netmask) == (host_ip & host_netmask) {
|
||||
println!(
|
||||
"hostip = {:?}\nhostmac={:?}\nip={:?}",
|
||||
host_netmask.to_be_bytes(),
|
||||
host_ip.to_be_bytes(),
|
||||
ip.to_be_bytes(),
|
||||
);
|
||||
target_ip = ip;
|
||||
}
|
||||
|
||||
if target_ip == 0 {
|
||||
let route_table = get_route_table();
|
||||
if let Some(gateway_ip) = route_table.get_gateway_ip(ip) {
|
||||
target_ip = gateway_ip;
|
||||
}
|
||||
}
|
||||
if target_ip == 0 {
|
||||
panic!("target should not route to me");
|
||||
}
|
||||
for i in 0..ARP_TABLE_SIZE {
|
||||
let item = &self.entry[i];
|
||||
if item.ip_addr == target_ip {
|
||||
return (item.hw_addr, target_ip, false);
|
||||
}
|
||||
}
|
||||
return (BROADCAST_MAC, target_ip, true);
|
||||
}
|
||||
|
||||
fn set_arp(&mut self, mac: [u8; 6], ip: u32) {
|
||||
println!("setting ip: {:?} is at {:?}", ip.to_be_bytes(), mac);
|
||||
for i in 0..ARP_TABLE_SIZE {
|
||||
let item = &mut self.entry[i];
|
||||
if item.ip_addr != 0 {
|
||||
if item.ip_addr == ip {
|
||||
item.hw_addr = mac;
|
||||
let nowage = ARPTIME.load(Ordering::Relaxed);
|
||||
item.arptime = nowage;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("set_arp 1");
|
||||
|
||||
let mut itemindex = ARP_TABLE_SIZE;
|
||||
for i in 0..ARP_TABLE_SIZE {
|
||||
let temp = &self.entry[i];
|
||||
println!("set arp 2");
|
||||
if temp.ip_addr == 0 {
|
||||
itemindex = i;
|
||||
println!("set arp 3: itemindex = {}", itemindex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let arptime = ARPTIME.load(Ordering::Relaxed);
|
||||
if itemindex == ARP_TABLE_SIZE {
|
||||
println!("set_arp 4");
|
||||
let mut tmpage = 0;
|
||||
let mut idx = 0;
|
||||
for i in 0..ARP_TABLE_SIZE {
|
||||
let temp = &self.entry[i];
|
||||
if (arptime - temp.arptime) > tmpage {
|
||||
tmpage = arptime - temp.arptime;
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
itemindex = idx;
|
||||
}
|
||||
println!("set_arp 5");
|
||||
let temp = &mut self.entry[itemindex];
|
||||
temp.arptime = arptime;
|
||||
temp.ip_addr = ip;
|
||||
temp.hw_addr = mac;
|
||||
println!("set arp 6: idx={} => {:?}", itemindex, temp);
|
||||
}
|
||||
|
||||
fn timer(&mut self) {
|
||||
let timer = ARPTIME.fetch_add(1, Ordering::Relaxed);
|
||||
for i in 0..ARP_TABLE_SIZE {
|
||||
let item = &mut self.entry[i];
|
||||
if item.ip_addr != 0 && (timer - item.arptime) >= ARP_MAX_AGE {
|
||||
item.ip_addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ArpRequestInfo {
|
||||
Lookup { ip: u32 },
|
||||
Set { ip: u32, mac: Mac },
|
||||
}
|
||||
|
||||
pub struct ArpRequest {
|
||||
req: ArpRequestInfo,
|
||||
tx: oneshot::Sender<ArpResponse>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ArpResponse {
|
||||
LookupResp {
|
||||
mac: Mac,
|
||||
ip: u32,
|
||||
do_arp_request: bool,
|
||||
},
|
||||
SetResp {
|
||||
ok: bool,
|
||||
},
|
||||
ArpRespError {
|
||||
msg: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArpActor {
|
||||
pub tx: Sender<ArpRequest>,
|
||||
}
|
||||
|
||||
impl ArpActor {
|
||||
pub fn new() -> Self {
|
||||
let (tx, rx) = channel(20);
|
||||
tokio::spawn(loop_arp_info(rx));
|
||||
Self { tx }
|
||||
}
|
||||
}
|
||||
|
||||
async fn loop_arp_info(mut rx: Receiver<ArpRequest>) {
|
||||
let mut arp = ArpInfo {
|
||||
entry: array::from_fn(|_i| ArpEntry::new()),
|
||||
};
|
||||
loop {
|
||||
tokio::select! {
|
||||
data = rx.recv() => {
|
||||
if let Some(d) = data {
|
||||
match d.req {
|
||||
ArpRequestInfo::Lookup{ip} => {
|
||||
let mac = arp.lookup_ip_mac(ip);
|
||||
if let Err(e) = d.tx.send(ArpResponse::LookupResp {
|
||||
mac: mac.0, ip: mac.1, do_arp_request: mac.2 }
|
||||
) {
|
||||
error!("failed to send back arp lookup feedback: {:?}", e);
|
||||
};
|
||||
}
|
||||
ArpRequestInfo::Set{ip, mac} => {
|
||||
arp.set_arp(mac, ip);
|
||||
if let Err(e) = d.tx.send(ArpResponse::SetResp { ok: true }) {
|
||||
error!("failed to send back arp set feedback: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = tokio::time::sleep(Duration::from_secs(10)) => {
|
||||
arp.timer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_arp_request(data: ArpRequestInfo) -> ArpResponse {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let arp = get_arp();
|
||||
if let Err(e) = arp.tx.send(ArpRequest { tx, req: data }).await {
|
||||
error!("failed to send arp request: {}", e);
|
||||
return ArpResponse::ArpRespError {
|
||||
msg: "failed to send arp request".to_owned(),
|
||||
};
|
||||
}
|
||||
match rx.await {
|
||||
Ok(res) => res,
|
||||
Err(e) => ArpResponse::ArpRespError { msg: e.to_string() },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_arp_request(srcmac: [u8; 6], dstip: u32, srcip: u32) -> Vec<u8> {
|
||||
let mut arphdr = ArpHdr::new();
|
||||
arphdr.ethhdr.dest = [0xff; 6];
|
||||
arphdr.dhwaddr = [0; 6];
|
||||
arphdr.ethhdr.src = srcmac;
|
||||
arphdr.shwaddr = srcmac;
|
||||
|
||||
arphdr.dipaddr = [(dstip >> 16) as u16, (dstip & 0xffff) as u16];
|
||||
arphdr.sipaddr = [(srcip >> 16) as u16, (srcip & 0xffff) as u16];
|
||||
|
||||
println!(
|
||||
"arphdr.sipaddr: {:?}, {:?}",
|
||||
arphdr.sipaddr[0].to_be_bytes(),
|
||||
arphdr.sipaddr[1].to_be_bytes()
|
||||
);
|
||||
println!(
|
||||
"arphdr.dipaddr: {:?}, {:?}",
|
||||
arphdr.dipaddr[0].to_be_bytes(),
|
||||
arphdr.dipaddr[1].to_be_bytes()
|
||||
);
|
||||
|
||||
arphdr.marshal_to_bytes()
|
||||
}
|
||||
@ -3,9 +3,12 @@ use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::config::TCP_PING_TIME;
|
||||
use crate::config::{NULL_MAC, TCP_PING_TIME};
|
||||
use crate::network::ipv6::run_ipv6;
|
||||
use crate::network::{get_edge, ping_to_sn, read_and_parse_packet, RegisterSuperFeedback};
|
||||
use crate::network::{
|
||||
generate_arp_request, get_edge, ping_to_sn, read_and_parse_packet, send_arp_request, ArpHdr,
|
||||
ArpRequestInfo, ArpResponse, RegisterSuperFeedback, ARP_REPLY, ARP_REQUEST,
|
||||
};
|
||||
use crate::pb::{
|
||||
encode_to_tcp_message, encode_to_udp_message, SdlData, SdlDevAddr, SdlRegisterSuper,
|
||||
SdlRegisterSuperAck, SdlRegisterSuperNak, SdlSendRegisterEvent, SdlStunRequest, Sdlv6Info,
|
||||
@ -13,13 +16,15 @@ use crate::pb::{
|
||||
use crate::tcp::{init_tcp_conn, EventType, NakMsgCode, PacketType, SdlanTcp};
|
||||
use crate::utils::{send_to_sock, CommandLine};
|
||||
use crate::ConnectionState;
|
||||
use etherparse::IpHeaders;
|
||||
use etherparse::ether_type::ARP;
|
||||
use etherparse::{Ethernet2Header, IpHeaders};
|
||||
use sdlan_sn_rs::config::{AF_INET, AF_INET6, SDLAN_DEFAULT_TTL};
|
||||
use sdlan_sn_rs::peer::{SdlanSock, V6Info};
|
||||
use sdlan_sn_rs::utils::Result;
|
||||
use sdlan_sn_rs::utils::{
|
||||
aes_encrypt, get_current_timestamp, ip_to_string, is_multi_broadcast, rsa_decrypt,
|
||||
BROADCAST_MAC,
|
||||
};
|
||||
use sdlan_sn_rs::utils::{Mac, Result};
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
@ -67,6 +72,11 @@ async fn handle_tcp_message(msg: SdlanTcp) {
|
||||
.ip
|
||||
.net_addr
|
||||
.store(dev.net_addr, Ordering::Relaxed);
|
||||
let mac = match dev.mac.try_into() {
|
||||
Err(_) => NULL_MAC,
|
||||
Ok(m) => m,
|
||||
};
|
||||
*edge.device_config.mac.write().unwrap() = mac;
|
||||
edge.device_config
|
||||
.ip
|
||||
.net_bit_len
|
||||
@ -200,10 +210,16 @@ async fn handle_tcp_event(edge: &Node, eventtype: EventType, eventprotobuf: &[u8
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let dst_mac = match reg.dst_mac.try_into() {
|
||||
Ok(m) => m,
|
||||
Err(e) => NULL_MAC,
|
||||
};
|
||||
|
||||
check_peer_registration_needed(
|
||||
edge,
|
||||
true,
|
||||
reg.dst_ip,
|
||||
dst_mac,
|
||||
// &v6_sock,
|
||||
&v6_sock,
|
||||
&SdlanSock {
|
||||
@ -288,6 +304,7 @@ pub async fn async_main(
|
||||
installed_channel,
|
||||
client_id: edge.config.node_uuid.clone(),
|
||||
dev_addr: Some(SdlDevAddr {
|
||||
mac: vec![],
|
||||
net_addr: 0,
|
||||
network_id: 0,
|
||||
net_bit_len: 0,
|
||||
@ -429,6 +446,7 @@ async fn send_stun_request(eee: &Node) {
|
||||
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,
|
||||
};
|
||||
@ -574,6 +592,14 @@ async fn read_and_parse_tun_packet(eee: &'static Node, buf: Vec<u8>) {
|
||||
|
||||
async fn edge_send_packet_to_net(eee: &Node, data: &[u8]) {
|
||||
debug!("edge send packet to net({} bytes): {:?}", data.len(), data);
|
||||
|
||||
let encrypt_key = eee.get_encrypt_key();
|
||||
if encrypt_key.len() == 0 {
|
||||
error!("drop tun packet due to encrypt key len is 0");
|
||||
return;
|
||||
}
|
||||
let src_mac = eee.device_config.get_mac();
|
||||
|
||||
match IpHeaders::from_slice(&data) {
|
||||
Ok((iphdr, _payload)) => {
|
||||
let Some(ipv4hdr) = iphdr.ipv4() else {
|
||||
@ -594,32 +620,76 @@ async fn edge_send_packet_to_net(eee: &Node, data: &[u8]) {
|
||||
debug!("drop tun packet due to not authed");
|
||||
return;
|
||||
}
|
||||
let encrypt_key = eee.get_encrypt_key();
|
||||
if encrypt_key.len() == 0 {
|
||||
error!("drop tun packet due to encrypt key len is 0");
|
||||
return;
|
||||
}
|
||||
let msg_size = data.len() as u64;
|
||||
let Ok(encrypted_flow) = aes_encrypt(encrypt_key.as_slice(), data) else {
|
||||
error!("failed to encrypt flow");
|
||||
return;
|
||||
};
|
||||
match send_arp_request(ArpRequestInfo::Lookup { ip: dstip }).await {
|
||||
ArpResponse::LookupResp {
|
||||
mac,
|
||||
ip,
|
||||
do_arp_request,
|
||||
} => {
|
||||
if do_arp_request {
|
||||
println!(
|
||||
"find ip: {:?} => {:?}",
|
||||
ip.to_be_bytes(),
|
||||
dstip.to_be_bytes()
|
||||
);
|
||||
let arp_msg = generate_arp_request(src_mac, ip, eee.device_config.get_ip());
|
||||
let Ok(encrypted) = aes_encrypt(&encrypt_key, &arp_msg) else {
|
||||
error!("failed to encrypt arp request");
|
||||
return;
|
||||
};
|
||||
// println!("arp_msg: {:?}", arp_msg);
|
||||
let data = SdlData {
|
||||
network_id: eee.network_id.load(Ordering::Relaxed),
|
||||
src_mac: Vec::from(src_mac),
|
||||
dst_mac: Vec::from([0xff; 6]),
|
||||
is_p2p: true,
|
||||
ttl: SDLAN_DEFAULT_TTL as u32,
|
||||
data: encrypted,
|
||||
};
|
||||
let data =
|
||||
encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
||||
// let data = marshal_message(&data);
|
||||
send_packet_to_net(eee, BROADCAST_MAC, &data, arp_msg.len() as u64).await;
|
||||
// edge.sock.send(data).await;
|
||||
// println!("should send arp");
|
||||
return;
|
||||
}
|
||||
|
||||
let message = SdlData {
|
||||
// TODO: network id should be stored in
|
||||
network_id: eee.network_id.load(Ordering::Relaxed),
|
||||
src_ip: eee.device_config.get_ip(),
|
||||
dst_ip: dstip,
|
||||
is_p2p: true,
|
||||
ttl: SDLAN_DEFAULT_TTL as u32,
|
||||
data: encrypted_flow,
|
||||
};
|
||||
debug!("sending SdlData: {:?}", message);
|
||||
let Ok(flow) = encode_to_udp_message(Some(message), PacketType::Data as u8) else {
|
||||
error!("failed to encode to udp message");
|
||||
return;
|
||||
};
|
||||
send_packet_to_net(eee, dstip, &flow, msg_size).await;
|
||||
// prepend the ether header
|
||||
let mut etherheader = Ethernet2Header::default();
|
||||
etherheader.destination = mac;
|
||||
etherheader.ether_type = etherparse::EtherType::IPV4;
|
||||
etherheader.source = src_mac;
|
||||
let mut packet = Vec::with_capacity(14 + data.len());
|
||||
packet.extend_from_slice(ðerheader.to_bytes()[..]);
|
||||
packet.extend_from_slice(&data);
|
||||
|
||||
let pkt_size = packet.len();
|
||||
println!("sending data with mac");
|
||||
|
||||
let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else {
|
||||
error!("failed to encrypt packet request");
|
||||
return;
|
||||
};
|
||||
let data = SdlData {
|
||||
is_p2p: true,
|
||||
network_id: eee.network_id.load(Ordering::Relaxed),
|
||||
ttl: SDLAN_DEFAULT_TTL as u32,
|
||||
src_mac: Vec::from(src_mac),
|
||||
dst_mac: Vec::from(mac),
|
||||
data: Vec::from(encrypted),
|
||||
};
|
||||
let msg = encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
||||
let size = msg.len();
|
||||
send_packet_to_net(eee, mac, &msg, pkt_size as u64).await;
|
||||
// let dstip = u32::from_be_bytes(ipv4hdr.0.destination);
|
||||
println!(
|
||||
"{:?} => {:?}, size={}",
|
||||
ipv4hdr.0.source, ipv4hdr.0.destination, size
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("failed to parse ip packet: {}", e.to_string());
|
||||
@ -627,13 +697,13 @@ async fn edge_send_packet_to_net(eee: &Node, data: &[u8]) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_packet_to_net(eee: &Node, dst_ip: u32, pkt: &[u8], size: u64) {
|
||||
let (dest_sock, is_p2p) = find_peer_destination(eee, dst_ip).await;
|
||||
async fn send_packet_to_net(eee: &Node, dst_mac: Mac, pkt: &[u8], size: u64) {
|
||||
let (dest_sock, is_p2p) = find_peer_destination(eee, dst_mac).await;
|
||||
if is_p2p {
|
||||
eee.stats.tx_p2p.fetch_add(size, Ordering::Relaxed);
|
||||
} else {
|
||||
eee.stats.tx_sup.fetch_add(size, Ordering::Relaxed);
|
||||
if is_multi_broadcast(dst_ip) {
|
||||
if is_multi_broadcast(&dst_mac) {
|
||||
eee.stats.tx_broadcast.fetch_add(size, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
@ -643,8 +713,8 @@ async fn send_packet_to_net(eee: &Node, dst_ip: u32, pkt: &[u8], size: u64) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn find_peer_destination(eee: &Node, dst_ip: u32) -> (SdlanSock, bool) {
|
||||
if is_multi_broadcast(dst_ip) {
|
||||
async fn find_peer_destination(eee: &Node, dst_mac: Mac) -> (SdlanSock, bool) {
|
||||
if is_multi_broadcast(&dst_mac) {
|
||||
return (
|
||||
eee.config.super_nodes[eee.config.super_node_index.load(Ordering::Relaxed) as usize]
|
||||
.deepcopy(),
|
||||
@ -653,11 +723,11 @@ async fn find_peer_destination(eee: &Node, dst_ip: u32) -> (SdlanSock, bool) {
|
||||
}
|
||||
let mut is_p2p = false;
|
||||
let result: SdlanSock;
|
||||
if let Some(dst) = eee.known_peers.get_peer(&dst_ip) {
|
||||
if let Some(dst) = eee.known_peers.get_peer(&dst_mac) {
|
||||
let now = get_current_timestamp();
|
||||
if now - dst.last_p2p.load(Ordering::Relaxed) >= ((dst.timeout / 2) as u64) {
|
||||
// too much time elapsed since we saw the peer, need to register again
|
||||
eee.known_peers.delete_peer_with_ip(&dst_ip);
|
||||
eee.known_peers.delete_peer_with_mac(&dst_mac);
|
||||
result = eee.config.super_nodes
|
||||
[eee.config.super_node_index.load(Ordering::Relaxed) as usize]
|
||||
.deepcopy();
|
||||
@ -674,7 +744,7 @@ async fn find_peer_destination(eee: &Node, dst_ip: u32) -> (SdlanSock, bool) {
|
||||
// println!("find peer_destination: {}", is_p2p);
|
||||
if !is_p2p {
|
||||
debug!("check_query_peer_info");
|
||||
super::packet::check_query_peer_info(eee, dst_ip).await;
|
||||
super::packet::check_query_peer_info(eee, dst_mac).await;
|
||||
}
|
||||
return (result, is_p2p);
|
||||
}
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
use sdlan_sn_rs::peer::IpSubnet;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use sdlan_sn_rs::{peer::IpSubnet, utils::Mac};
|
||||
|
||||
pub struct DeviceConfig {
|
||||
pub mac: RwLock<Mac>,
|
||||
pub ip: IpSubnet,
|
||||
}
|
||||
|
||||
impl DeviceConfig {
|
||||
pub fn new() -> Self {
|
||||
DeviceConfig {
|
||||
mac: RwLock::new([0; 6]),
|
||||
ip: IpSubnet::new(0, 0),
|
||||
}
|
||||
}
|
||||
@ -28,6 +32,10 @@ impl DeviceConfig {
|
||||
pub fn get_net_bit(&self) -> u8 {
|
||||
self.ip.net_bit_len()
|
||||
}
|
||||
|
||||
pub fn get_mac(&self) -> Mac {
|
||||
*self.mac.read().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// The mode in which open the virtual network adapter.
|
||||
|
||||
@ -9,10 +9,15 @@ mod ipv6;
|
||||
mod packet;
|
||||
pub use packet::*;
|
||||
|
||||
mod arp;
|
||||
pub use arp::*;
|
||||
|
||||
mod route;
|
||||
pub use route::*;
|
||||
|
||||
#[cfg_attr(target_os = "linux", path = "tun_linux.rs")]
|
||||
#[cfg_attr(target_os = "windows", path = "tun_win.rs")]
|
||||
mod tun;
|
||||
pub use tun::get_install_channel;
|
||||
|
||||
mod device;
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ use super::device::{DeviceConfig, Mode};
|
||||
use super::tun::{new_iface, Iface};
|
||||
use tokio::fs::File;
|
||||
|
||||
use sdlan_sn_rs::utils::{gen_rsa_keys, load_private_key_file};
|
||||
use sdlan_sn_rs::utils::{gen_rsa_keys, load_private_key_file, Mac};
|
||||
use sdlan_sn_rs::utils::{Result, SDLanError};
|
||||
|
||||
static EDGE: OnceCell<Node> = OnceCell::new();
|
||||
@ -473,7 +473,7 @@ impl Node {
|
||||
}
|
||||
|
||||
pub struct PeerMap {
|
||||
pub peers: DashMap<u32, Arc<EdgePeer>>,
|
||||
pub peers: DashMap<Mac, Arc<EdgePeer>>,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
@ -484,7 +484,7 @@ impl PeerMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_peer(&self, ip: &u32) -> Option<Arc<EdgePeer>> {
|
||||
pub fn get_peer(&self, ip: &Mac) -> Option<Arc<EdgePeer>> {
|
||||
if let Some(v) = self.peers.get(ip) {
|
||||
Some(v.clone())
|
||||
} else {
|
||||
@ -506,15 +506,12 @@ impl PeerMap {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn delete_peer_with_ip(&self, ip: &u32) {
|
||||
self.peers.remove(ip);
|
||||
pub fn delete_peer_with_mac(&self, mac: &Mac) {
|
||||
self.peers.remove(mac);
|
||||
}
|
||||
|
||||
pub fn insert_peer(&self, p: Arc<EdgePeer>) {
|
||||
let net_addr = p.dev_addr.net_addr();
|
||||
if net_addr != 0 {
|
||||
self.peers.insert(net_addr, p);
|
||||
}
|
||||
pub fn insert_peer(&self, mac: Mac, p: Arc<EdgePeer>) {
|
||||
self.peers.insert(mac, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,6 +585,7 @@ pub struct NodeConfig {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EdgePeer {
|
||||
// pub mac: Mac,
|
||||
pub dev_addr: IpSubnet,
|
||||
|
||||
// 对端对外开放的ip和端口信息
|
||||
@ -613,6 +611,7 @@ pub struct EdgePeer {
|
||||
|
||||
impl EdgePeer {
|
||||
pub fn new(
|
||||
// mac: Mac,
|
||||
net_addr: u32,
|
||||
net_bit_len: u8,
|
||||
sock: &SdlanSock,
|
||||
@ -629,6 +628,7 @@ impl EdgePeer {
|
||||
})
|
||||
}
|
||||
Self {
|
||||
// mac,
|
||||
dev_addr: IpSubnet::new(net_addr, net_bit_len),
|
||||
sock: RwLock::new(sock.deepcopy()),
|
||||
_v6_info: RwLock::new(v6_info),
|
||||
|
||||
@ -4,8 +4,12 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::utils::mac_to_string;
|
||||
|
||||
use crate::{
|
||||
config::REGISTER_INTERVAL,
|
||||
config::{NULL_MAC, REGISTER_INTERVAL},
|
||||
get_edge,
|
||||
network::{send_arp_request, ArpHdr, ArpRequestInfo, ARP_REPLY, ARP_REQUEST},
|
||||
pb::{
|
||||
encode_to_tcp_message, encode_to_udp_message, SdlData, SdlEmpty, SdlPeerInfo, SdlQueryInfo,
|
||||
SdlRegister, SdlRegisterAck, SdlStunProbeReply,
|
||||
@ -13,14 +17,14 @@ use crate::{
|
||||
tcp::{get_tcp_conn, PacketType},
|
||||
utils::{send_to_sock, Socket},
|
||||
};
|
||||
use etherparse::IpHeaders;
|
||||
use etherparse::{ether_type::ARP, Ethernet2Header, IpHeaders};
|
||||
use prost::Message;
|
||||
use sdlan_sn_rs::{
|
||||
config::{AF_INET, AF_INET6},
|
||||
peer::{is_sdlan_sock_equal, SdlanSock, V6Info},
|
||||
utils::{
|
||||
aes_decrypt, get_current_timestamp, get_sdlan_sock_from_socketaddr, ip_to_string,
|
||||
is_multi_broadcast, Result, SDLanError,
|
||||
is_multi_broadcast, Mac, Result, SDLanError, BROADCAST_MAC,
|
||||
},
|
||||
};
|
||||
use std::sync::Arc;
|
||||
@ -107,21 +111,24 @@ pub async fn handle_packet(eee: &Node, addr: SocketAddr, buf: &[u8]) -> Result<(
|
||||
error!("failed to decode to SDLData");
|
||||
return Err(SDLanError::NormalError("failed to decode to SDLData"));
|
||||
};
|
||||
let Ok(src_mac) = data.src_mac.clone().try_into() else {
|
||||
error!("failed to convert src mac");
|
||||
return Err(SDLanError::NormalError("failed to convert vec to Mac"));
|
||||
};
|
||||
// let from_sock = get_sdlan_sock_from_socketaddr(addr).unwrap();
|
||||
if data.is_p2p {
|
||||
debug!("[P2P] Rx data from {}", from_sock.to_string());
|
||||
} else {
|
||||
debug!(
|
||||
"[PsP] Rx data from {} via {}",
|
||||
ip_to_string(&data.src_ip),
|
||||
mac_to_string(&src_mac),
|
||||
from_sock.to_string()
|
||||
);
|
||||
}
|
||||
if data.is_p2p {
|
||||
check_peer_registration_needed(eee, !data.is_p2p, data.src_ip, &None, &from_sock)
|
||||
.await;
|
||||
check_peer_registration_needed(eee, !data.is_p2p, src_mac, &None, &from_sock).await;
|
||||
}
|
||||
handle_tun_packet(eee, !data.is_p2p, data).await;
|
||||
handle_tun_packet(eee, &from_sock, !data.is_p2p, data).await;
|
||||
}
|
||||
PacketType::StunProbeReply => {
|
||||
let Ok(reply) = SdlStunProbeReply::decode(&buf[1..]) else {
|
||||
@ -232,6 +239,10 @@ pub async fn handle_packet_peer_info(
|
||||
};
|
||||
|
||||
debug!("got peer info: {:?}", pi);
|
||||
let Ok(dst_mac) = pi.dst_mac.try_into() else {
|
||||
error!("mac is null");
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if pi.v4_info.is_none() {
|
||||
error!("PEER's v4_info is none");
|
||||
@ -254,10 +265,10 @@ pub async fn handle_packet_peer_info(
|
||||
}
|
||||
// let src_ip = u32::from_be_bytes(v4_u32);
|
||||
|
||||
if pi.dst_ip == 0 {
|
||||
if dst_mac == NULL_MAC {
|
||||
// pong from sn
|
||||
} else {
|
||||
match eee.pending_peers.get_peer(&pi.dst_ip) {
|
||||
match eee.pending_peers.get_peer(&dst_mac) {
|
||||
Some(edgeinfo) => {
|
||||
let mut sock = SdlanSock {
|
||||
family: AF_INET,
|
||||
@ -268,19 +279,19 @@ pub async fn handle_packet_peer_info(
|
||||
*(edgeinfo.sock.write().unwrap()) = sock.deepcopy();
|
||||
info!(
|
||||
"Rx PEERINFO for {}: is at {}",
|
||||
ip_to_string(&pi.dst_ip),
|
||||
mac_to_string(&dst_mac),
|
||||
sock.to_string()
|
||||
);
|
||||
let mut v6_info = None;
|
||||
if v6_port != 0 {
|
||||
v6_info = Some(V6Info { port: v6_port, v6 })
|
||||
}
|
||||
send_register(eee, &sock, &v6_info).await;
|
||||
send_register(eee, &sock, dst_mac, &v6_info).await;
|
||||
|
||||
// register_with_local_peers(eee).await;
|
||||
}
|
||||
None => {
|
||||
debug!("Rx PEERINFO unknown peer: {}", ip_to_string(&pi.dst_ip));
|
||||
debug!("Rx PEERINFO unknown peer: {}", mac_to_string(&dst_mac));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -372,15 +383,23 @@ async fn handle_packet_register_ack(
|
||||
};
|
||||
|
||||
let origin_sender = sender_sock;
|
||||
let Ok(src_mac) = ack.src_mac.try_into() else {
|
||||
error!("failed to get src_mac");
|
||||
return Ok(());
|
||||
};
|
||||
let Ok(dst_mac) = ack.dst_mac.try_into() else {
|
||||
error!("failed to get dst_mac");
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
debug!(
|
||||
"Rx REGISTER ACK from {} [{}] to {} via {}",
|
||||
ip_to_string(&ack.src_ip),
|
||||
mac_to_string(&src_mac),
|
||||
origin_sender.to_string(),
|
||||
ip_to_string(&ack.dst_ip),
|
||||
mac_to_string(&dst_mac),
|
||||
sender_sock.to_string(),
|
||||
);
|
||||
peer_set_p2p_confirmed(eee, ack.src_ip, sender_sock);
|
||||
peer_set_p2p_confirmed(eee, src_mac, sender_sock);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -404,27 +423,36 @@ async fn handle_packet_register(
|
||||
|
||||
let origin_sender = sender_sock;
|
||||
|
||||
let via_multicast = is_multi_broadcast(reg.dst_ip);
|
||||
if via_multicast && reg.src_ip == eee.device_config.get_ip() {
|
||||
let Ok(src_mac) = reg.src_mac.clone().try_into() else {
|
||||
error!("[REGISTER] failed to get src_mac");
|
||||
return Ok(());
|
||||
};
|
||||
let Ok(dst_mac) = reg.dst_mac.clone().try_into() else {
|
||||
error!("[REGISTER] failed to get dst_mac");
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let via_multicast = is_multi_broadcast(&dst_mac);
|
||||
if via_multicast && src_mac == eee.device_config.get_mac() {
|
||||
debug!("skipping register from self");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if !from_sn {
|
||||
info!("[P2P] Rx REGISTER from {}", sender_sock.to_string());
|
||||
eee.pending_peers.delete_peer_with_ip(®.src_ip);
|
||||
eee.pending_peers.delete_peer_with_mac(&src_mac);
|
||||
send_register_ack(eee, origin_sender, ®).await;
|
||||
} else {
|
||||
info!(
|
||||
"[PsP] Rx REGISTER from {} [{}] to {} via {}",
|
||||
ip_to_string(®.src_ip),
|
||||
ip_to_string(®.dst_ip),
|
||||
mac_to_string(&src_mac),
|
||||
mac_to_string(&dst_mac),
|
||||
sender_sock.to_string(),
|
||||
origin_sender.to_string(),
|
||||
);
|
||||
}
|
||||
// check_peer_registration_needed(eee, from_sn, reg.src_ip, &None, origin_sender).await;
|
||||
check_peer_registration_needed(eee, from_sn, reg.src_ip, &None, origin_sender).await;
|
||||
check_peer_registration_needed(eee, from_sn, src_mac, &None, origin_sender).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -481,20 +509,20 @@ async fn handle_packet_packet(
|
||||
pub async fn check_peer_registration_needed(
|
||||
eee: &Node,
|
||||
from_sn: bool,
|
||||
src_ip: u32,
|
||||
src_mac: Mac,
|
||||
_v6_info: &Option<V6Info>,
|
||||
peer_sock: &SdlanSock,
|
||||
) {
|
||||
let mut p = eee.known_peers.get_peer(&src_ip);
|
||||
let mut p = eee.known_peers.get_peer(&src_mac);
|
||||
if let None = p {
|
||||
p = eee.known_peers.get_peer_by_sock(peer_sock);
|
||||
if let Some(ref k) = p {
|
||||
eee.known_peers.insert_peer(k.clone());
|
||||
eee.known_peers.insert_peer(src_mac, k.clone());
|
||||
}
|
||||
}
|
||||
match p {
|
||||
None => {
|
||||
let _ = register_with_new_peer(eee, from_sn, src_ip, _v6_info, peer_sock).await;
|
||||
let _ = register_with_new_peer(eee, from_sn, src_mac, _v6_info, peer_sock).await;
|
||||
// unimplemented!();
|
||||
}
|
||||
Some(k) => {
|
||||
@ -513,7 +541,7 @@ pub async fn check_peer_registration_needed(
|
||||
let last_seen = k.last_seen.load(Ordering::Relaxed);
|
||||
// more than 3 seconds
|
||||
if now - last_seen > 1 {
|
||||
check_known_peer_sock_change(eee, from_sn, src_ip, peer_sock, now, ipv4_to_ipv6)
|
||||
check_known_peer_sock_change(eee, from_sn, src_mac, peer_sock, now, ipv4_to_ipv6)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
@ -523,28 +551,28 @@ pub async fn check_peer_registration_needed(
|
||||
async fn check_known_peer_sock_change(
|
||||
eee: &Node,
|
||||
from_sn: bool,
|
||||
ip: u32,
|
||||
mac: Mac,
|
||||
// v6_info: &Option<V6Info>,
|
||||
// dev_addr: &IpSubnet,
|
||||
peersock: &SdlanSock,
|
||||
when: u64,
|
||||
ipv4_to_ipv6: bool,
|
||||
) {
|
||||
if is_multi_broadcast(ip) {
|
||||
if is_multi_broadcast(&mac) {
|
||||
return;
|
||||
}
|
||||
match eee.known_peers.get_peer(&ip) {
|
||||
match eee.known_peers.get_peer(&mac) {
|
||||
Some(p) => {
|
||||
if !ipv4_to_ipv6 && !is_sdlan_sock_equal(&p.sock.read().unwrap(), peersock) {
|
||||
if !from_sn {
|
||||
info!(
|
||||
"peer changed: {}: {} -> {}",
|
||||
ip_to_string(&ip),
|
||||
mac_to_string(&mac),
|
||||
&p.sock.read().unwrap().to_string(),
|
||||
peersock.to_string()
|
||||
);
|
||||
eee.known_peers.delete_peer_with_ip(&ip);
|
||||
register_with_new_peer(eee, from_sn, ip, &None, peersock).await;
|
||||
eee.known_peers.delete_peer_with_mac(&mac);
|
||||
register_with_new_peer(eee, from_sn, mac, &None, peersock).await;
|
||||
} else {
|
||||
// from sn, sn could see a different sock with us, just ignore it
|
||||
}
|
||||
@ -560,17 +588,18 @@ async fn check_known_peer_sock_change(
|
||||
async fn register_with_new_peer(
|
||||
eee: &Node,
|
||||
from_sn: bool,
|
||||
ip: u32,
|
||||
mac: Mac,
|
||||
v6_info: &Option<V6Info>,
|
||||
// dev_addr: &IpSubnet,
|
||||
peersock: &SdlanSock,
|
||||
) {
|
||||
let now = get_current_timestamp();
|
||||
let mut scan = eee.pending_peers.get_peer(&ip);
|
||||
let mut scan = eee.pending_peers.get_peer(&mac);
|
||||
if let None = scan {
|
||||
// such ip not found in pending
|
||||
let temp = Arc::new(EdgePeer::new(
|
||||
ip,
|
||||
// mac,
|
||||
0,
|
||||
eee.device_config.get_net_bit(),
|
||||
peersock,
|
||||
&None,
|
||||
@ -578,10 +607,10 @@ async fn register_with_new_peer(
|
||||
));
|
||||
debug!(
|
||||
"===> new pending {} => {}",
|
||||
ip_to_string(&ip),
|
||||
mac_to_string(&mac),
|
||||
peersock.to_string(),
|
||||
);
|
||||
eee.pending_peers.insert_peer(temp.clone());
|
||||
eee.pending_peers.insert_peer(mac, temp.clone());
|
||||
scan = Some(temp);
|
||||
debug!("Pending size: {}", eee.pending_peers.peers.len());
|
||||
|
||||
@ -593,31 +622,32 @@ async fn register_with_new_peer(
|
||||
let mut alter = 16;
|
||||
if let Ok(ttl) = eee.udp_sock_v4.ttl() {
|
||||
let mut temp = peersock.deepcopy();
|
||||
send_register(eee, &temp, v6_info).await;
|
||||
send_register(eee, &temp, mac, v6_info).await;
|
||||
|
||||
let _ = eee.udp_sock_v4.set_ttl(eee.config.register_ttl as u32);
|
||||
while alter > 0 {
|
||||
temp.port += 1;
|
||||
send_register(eee, &temp, v6_info).await;
|
||||
send_register(eee, &temp, mac, v6_info).await;
|
||||
alter -= 1;
|
||||
}
|
||||
let _ = eee.udp_sock_v4.set_ttl(ttl);
|
||||
}
|
||||
} else {
|
||||
// Normal STUN
|
||||
send_register(eee, peersock, v6_info).await;
|
||||
send_register(eee, peersock, mac, v6_info).await;
|
||||
}
|
||||
// 发送给sn
|
||||
send_register(
|
||||
eee,
|
||||
&eee.config.super_nodes
|
||||
[eee.config.super_node_index.load(Ordering::Relaxed) as usize],
|
||||
mac,
|
||||
v6_info,
|
||||
)
|
||||
.await;
|
||||
} else {
|
||||
// P2P register, send directly
|
||||
send_register(eee, peersock, v6_info).await;
|
||||
send_register(eee, peersock, mac, v6_info).await;
|
||||
}
|
||||
register_with_local_peers(eee).await;
|
||||
} else {
|
||||
@ -634,11 +664,11 @@ async fn register_with_new_peer(
|
||||
async fn register_with_local_peers(eee: &Node) {
|
||||
if eee.config.allow_p2p {
|
||||
debug!("send register to multicast sock");
|
||||
send_register(eee, &eee.multicast_sock, &None).await;
|
||||
send_register(eee, &eee.multicast_sock, NULL_MAC, &None).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_register(eee: &Node, sock: &SdlanSock, _v6_info: &Option<V6Info>) {
|
||||
async fn send_register(eee: &Node, sock: &SdlanSock, mac: Mac, _v6_info: &Option<V6Info>) {
|
||||
if !eee.config.allow_p2p {
|
||||
debug!("skipping register as p2p is disabled");
|
||||
return;
|
||||
@ -651,8 +681,10 @@ async fn send_register(eee: &Node, sock: &SdlanSock, _v6_info: &Option<V6Info>)
|
||||
|
||||
let register = SdlRegister {
|
||||
network_id: network_id,
|
||||
src_ip: eee.device_config.get_ip(),
|
||||
dst_ip: u32::from_be_bytes(sock.v4),
|
||||
src_mac: Vec::from(eee.device_config.get_mac()),
|
||||
// src_ip: eee.device_config.get_ip(),
|
||||
dst_mac: Vec::from(mac),
|
||||
// dst_ip: u32::from_be_bytes(sock.v4),
|
||||
};
|
||||
|
||||
let msg = encode_to_udp_message(Some(register), PacketType::Register as u8).unwrap();
|
||||
@ -685,6 +717,7 @@ async fn send_register(eee: &Node, sock: &SdlanSock, _v6_info: &Option<V6Info>)
|
||||
|
||||
async fn handle_tun_packet(
|
||||
eee: &Node,
|
||||
from_sock: &SdlanSock,
|
||||
from_sn: bool,
|
||||
pkt: SdlData, //orig_sender: &SdlanSock
|
||||
) {
|
||||
@ -706,8 +739,13 @@ async fn handle_tun_packet(
|
||||
let data = origin.unwrap();
|
||||
let msg_size = data.len() as u64;
|
||||
|
||||
let Ok(dst_mac) = pkt.dst_mac.try_into() else {
|
||||
error!("[PACKET] failed to decode dst_mac");
|
||||
return;
|
||||
};
|
||||
|
||||
if from_sn {
|
||||
if is_multi_broadcast(pkt.dst_ip) {
|
||||
if is_multi_broadcast(&dst_mac) {
|
||||
eee.stats
|
||||
.rx_broadcast
|
||||
.fetch_add(msg_size, Ordering::Relaxed);
|
||||
@ -719,25 +757,94 @@ async fn handle_tun_packet(
|
||||
eee.stats.last_p2p.store(now, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
// TODO: parse the mac
|
||||
debug!("got packet from sock, will send to tun");
|
||||
match IpHeaders::from_slice(&data) {
|
||||
Ok((iphdr, _)) => {
|
||||
if let Some(ipv4hdr) = iphdr.ipv4() {
|
||||
let dstip = u32::from_be_bytes(ipv4hdr.0.destination);
|
||||
if !is_multi_broadcast(dstip) && dstip != eee.device_config.get_ip() {
|
||||
// should not routed to me
|
||||
error!("should not routed to me");
|
||||
return;
|
||||
}
|
||||
// packet should be sent to dev
|
||||
debug!("writing {} bytes to tun: {:?}", data.len(), data);
|
||||
if let Err(e) = eee.device.send(&data) {
|
||||
error!("failed to write to tun: {}", e.to_string());
|
||||
match Ethernet2Header::from_slice(&data) {
|
||||
Ok((hdr, rest)) => {
|
||||
let edge = get_edge();
|
||||
let self_mac = edge.device_config.get_mac();
|
||||
if hdr.destination != self_mac && hdr.destination != BROADCAST_MAC {
|
||||
error!("packet not direct to us");
|
||||
return;
|
||||
}
|
||||
|
||||
if hdr.ether_type == ARP {
|
||||
let mut arp = ArpHdr::from_slice(&data);
|
||||
let self_ip = edge.device_config.get_ip();
|
||||
|
||||
println!("self_ip: {:?}", self_ip.to_be_bytes());
|
||||
let from_ip = ((arp.sipaddr[0] as u32) << 16) + arp.sipaddr[1] as u32;
|
||||
println!("from_ip: {:?}", from_ip.to_be_bytes());
|
||||
let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32;
|
||||
println!("dest_ip: {:?}", dest_ip.to_be_bytes());
|
||||
|
||||
match arp.opcode {
|
||||
ARP_REQUEST => {
|
||||
// handle ARP REQUEST
|
||||
if arp.ethhdr.dest != [0xff; 6] {
|
||||
println!("ARP REQUEST not broadcast");
|
||||
return;
|
||||
}
|
||||
if dest_ip == self_ip {
|
||||
send_arp_request(ArpRequestInfo::Set {
|
||||
ip: from_ip,
|
||||
mac: arp.shwaddr,
|
||||
})
|
||||
.await;
|
||||
// target to us
|
||||
arp.opcode = ARP_REPLY;
|
||||
arp.dhwaddr = arp.shwaddr;
|
||||
arp.shwaddr = self_mac;
|
||||
arp.ethhdr.src = self_mac;
|
||||
arp.ethhdr.dest = arp.dhwaddr;
|
||||
|
||||
arp.dipaddr = arp.sipaddr;
|
||||
|
||||
arp.sipaddr =
|
||||
[((self_ip >> 16) & 0xffff) as u16, (self_ip & 0xffff) as u16];
|
||||
|
||||
let data = SdlData {
|
||||
is_p2p: true,
|
||||
ttl: 2,
|
||||
network_id: edge.network_id.load(Ordering::Relaxed),
|
||||
src_mac: Vec::from(self_mac),
|
||||
dst_mac: Vec::from(arp.dhwaddr),
|
||||
data: arp.marshal_to_bytes(),
|
||||
};
|
||||
|
||||
let v =
|
||||
encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
||||
println!("xxxx send arp reply");
|
||||
send_to_sock(edge, &v, from_sock);
|
||||
// edge.sock.send(v).await;
|
||||
}
|
||||
}
|
||||
ARP_REPLY => {
|
||||
println!("got arp reply");
|
||||
|
||||
println!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes());
|
||||
if dest_ip == self_ip {
|
||||
send_arp_request(ArpRequestInfo::Set {
|
||||
ip: from_ip,
|
||||
mac: arp.shwaddr,
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
other => {
|
||||
println!("unknown arp type info");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("got ip packet");
|
||||
println!("got data: {:?}", rest);
|
||||
edge.device.send(rest);
|
||||
// edge.tun.send_data_to_tun(Vec::from(hdr.1)).await;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("failed to parse ip packet: {}", e.to_string());
|
||||
error!("failed to parse tap packet: {}", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -752,10 +859,11 @@ async fn send_register_ack(eee: &Node, orig_sender: &SdlanSock, reg: &SdlRegiste
|
||||
error!("not authed");
|
||||
return;
|
||||
}
|
||||
let src_mac = reg.src_mac.clone();
|
||||
let ack = SdlRegisterAck {
|
||||
network_id,
|
||||
src_ip: eee.device_config.get_ip(),
|
||||
dst_ip: reg.src_ip,
|
||||
src_mac: Vec::from(eee.device_config.get_mac()),
|
||||
dst_mac: src_mac,
|
||||
};
|
||||
let Ok(ack) = encode_to_udp_message(Some(ack), PacketType::RegisterACK as u8) else {
|
||||
error!("failed to encode to udp message");
|
||||
@ -764,8 +872,8 @@ async fn send_register_ack(eee: &Node, orig_sender: &SdlanSock, reg: &SdlRegiste
|
||||
let _ = send_to_sock(eee, &ack, orig_sender).await;
|
||||
}
|
||||
|
||||
fn peer_set_p2p_confirmed(eee: &Node, src_ip: u32, sender_sock: &SdlanSock) {
|
||||
let mut scan = eee.pending_peers.get_peer(&src_ip);
|
||||
fn peer_set_p2p_confirmed(eee: &Node, src_mac: Mac, sender_sock: &SdlanSock) {
|
||||
let mut scan = eee.pending_peers.get_peer(&src_mac);
|
||||
if let None = scan {
|
||||
scan = eee.pending_peers.get_peer_by_sock(sender_sock);
|
||||
}
|
||||
@ -778,17 +886,20 @@ fn peer_set_p2p_confirmed(eee: &Node, src_ip: u32, sender_sock: &SdlanSock) {
|
||||
}
|
||||
|
||||
let mut scan = scan.unwrap();
|
||||
eee.pending_peers.delete_peer_with_ip(&src_ip);
|
||||
match eee.known_peers.get_peer(&src_ip) {
|
||||
eee.pending_peers.delete_peer_with_mac(&src_mac);
|
||||
match eee.known_peers.get_peer(&src_mac) {
|
||||
Some(scantmp) => {
|
||||
eee.known_peers.delete_peer_with_ip(&src_ip);
|
||||
eee.known_peers.delete_peer_with_mac(&src_mac);
|
||||
scan = scantmp;
|
||||
// set the remote peer sock
|
||||
*scan.sock.write().unwrap() = sender_sock.deepcopy();
|
||||
scan.dev_addr.net_addr.store(src_ip, Ordering::Relaxed);
|
||||
// scan.mac = src_mac;
|
||||
/*
|
||||
scan.dev_addr.net_addr.store(&src_mac, Ordering::Relaxed);
|
||||
scan.dev_addr
|
||||
.net_bit_len
|
||||
.store(eee.device_config.get_net_bit(), Ordering::Relaxed);
|
||||
*/
|
||||
}
|
||||
None => {
|
||||
*(scan.sock.write().unwrap()) = sender_sock.deepcopy();
|
||||
@ -798,20 +909,20 @@ fn peer_set_p2p_confirmed(eee: &Node, src_ip: u32, sender_sock: &SdlanSock) {
|
||||
scan.last_p2p.store(now, Ordering::Relaxed);
|
||||
scan.last_seen.store(now, Ordering::Relaxed);
|
||||
|
||||
let ip_string = ip_to_string(&src_ip);
|
||||
let mac_string = mac_to_string(&src_mac);
|
||||
let sock_string = sender_sock.to_string();
|
||||
info!(
|
||||
"P2P connection established: {} [{}]",
|
||||
&ip_string, &sock_string,
|
||||
&mac_string, &sock_string,
|
||||
);
|
||||
debug!("==> new peer: {} -> {}", &ip_string, &sock_string,);
|
||||
eee.known_peers.insert_peer(scan);
|
||||
debug!("==> new peer: {} -> {}", &mac_string, &sock_string,);
|
||||
eee.known_peers.insert_peer(src_mac, scan);
|
||||
}
|
||||
|
||||
pub async fn check_query_peer_info(eee: &Node, dst_ip: u32) {
|
||||
pub async fn check_query_peer_info(eee: &Node, mac: Mac) {
|
||||
let scan: Arc<EdgePeer>;
|
||||
let now = get_current_timestamp();
|
||||
match eee.pending_peers.get_peer(&dst_ip) {
|
||||
match eee.pending_peers.get_peer(&mac) {
|
||||
None => {
|
||||
let sock = SdlanSock {
|
||||
family: AF_INET,
|
||||
@ -820,14 +931,15 @@ pub async fn check_query_peer_info(eee: &Node, dst_ip: u32) {
|
||||
v6: [0; 16],
|
||||
};
|
||||
let peer = Arc::new(EdgePeer::new(
|
||||
dst_ip,
|
||||
// mac,
|
||||
0,
|
||||
eee.device_config.get_net_bit(),
|
||||
&sock,
|
||||
&None,
|
||||
now,
|
||||
));
|
||||
debug!("insert peer {} to pending", ip_to_string(&dst_ip));
|
||||
eee.pending_peers.insert_peer(peer.clone());
|
||||
debug!("insert peer {} to pending", mac_to_string(&mac));
|
||||
eee.pending_peers.insert_peer(mac, peer.clone());
|
||||
scan = peer;
|
||||
}
|
||||
Some(s) => {
|
||||
@ -850,22 +962,24 @@ pub async fn check_query_peer_info(eee: &Node, dst_ip: u32) {
|
||||
)
|
||||
.await;
|
||||
*/
|
||||
debug!("sending query for {}", ip_to_string(&dst_ip));
|
||||
debug!("sending query for {}", mac_to_string(&mac));
|
||||
register_with_local_peers(eee).await;
|
||||
if let Ok(()) = send_query_peer(eee, dst_ip).await {
|
||||
if let Ok(()) = send_query_peer(eee, mac).await {
|
||||
scan.last_sent_query.store(now, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_query_peer(eee: &Node, dst_ip: u32) -> Result<()> {
|
||||
async fn send_query_peer(eee: &Node, dst_mac: Mac) -> Result<()> {
|
||||
let network_id = eee.network_id.load(Ordering::Relaxed);
|
||||
|
||||
if network_id == 0 {
|
||||
error!("not authed");
|
||||
return Err(SDLanError::NormalError("not connected"));
|
||||
}
|
||||
let query = SdlQueryInfo { dst_ip };
|
||||
let query = SdlQueryInfo {
|
||||
dst_mac: Vec::from(dst_mac),
|
||||
};
|
||||
|
||||
let Ok(content) = encode_to_tcp_message(
|
||||
Some(query),
|
||||
|
||||
124
src/network/route.rs
Normal file
124
src/network/route.rs
Normal file
@ -0,0 +1,124 @@
|
||||
use std::{net::Ipv4Addr, sync::RwLock};
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use sdlan_sn_rs::utils::net_bit_len_to_mask;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RouteTable {
|
||||
content: RwLock<Vec<RouteInfo>>,
|
||||
}
|
||||
|
||||
static ROUTETABLE: OnceCell<RouteTable> = OnceCell::new();
|
||||
|
||||
pub fn init_route() {
|
||||
let rt = RouteTable::new();
|
||||
ROUTETABLE.set(rt).unwrap();
|
||||
}
|
||||
|
||||
pub fn get_route_table() -> &'static RouteTable {
|
||||
ROUTETABLE.get().unwrap()
|
||||
}
|
||||
|
||||
impl RouteTable {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
content: RwLock::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_gateway_ip(&self, net_ip: u32) -> Option<u32> {
|
||||
let routes = self.content.read().unwrap();
|
||||
for route in &*routes {
|
||||
println!("route: {:?}", route.to_string());
|
||||
if (route.net_ip & route.net_mask) == (net_ip & route.net_mask) {
|
||||
// found
|
||||
return Some(route.gateway_ip);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn del_route(&self, net_ip: u32, net_mask: u32) {
|
||||
let mut routes = self.content.write().unwrap();
|
||||
let mut remove_idx = routes.len();
|
||||
for i in 0..routes.len() {
|
||||
let route = &routes[i];
|
||||
if route.net_ip == net_ip && route.net_mask == net_mask {
|
||||
remove_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if remove_idx < routes.len() {
|
||||
routes.remove(remove_idx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_route(&self, net_ip: u32, net_mask: u32, gateway_ip: u32) -> Result<(), String> {
|
||||
{
|
||||
let cnt = self.content.read().unwrap();
|
||||
let net = net_ip & net_mask;
|
||||
for route in &*cnt {
|
||||
if (route.net_ip & route.net_mask) == net {
|
||||
return Err("route exists".to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut routes = self.content.write().unwrap();
|
||||
routes.push(RouteInfo {
|
||||
net_ip,
|
||||
net_mask,
|
||||
gateway_ip,
|
||||
})
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RouteInfo {
|
||||
pub net_ip: u32,
|
||||
pub net_mask: u32,
|
||||
pub gateway_ip: u32,
|
||||
}
|
||||
|
||||
impl RouteInfo {
|
||||
pub fn to_string(&self) -> String {
|
||||
format!(
|
||||
"{:?} mask={:?}, gateway={:?}",
|
||||
self.net_ip.to_be_bytes(),
|
||||
self.net_mask.to_be_bytes(),
|
||||
self.gateway_ip.to_be_bytes()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ip, mask, gateway
|
||||
pub fn parse_route(route: String) -> Vec<(u32, u32, u32)> {
|
||||
let mut result = Vec::new();
|
||||
let routes: Vec<_> = route.split(",").collect();
|
||||
for route in routes {
|
||||
let route_info: Vec<_> = route.split(";").collect();
|
||||
println!("got route info: {:?}", route_info);
|
||||
if route_info.len() != 2 {
|
||||
println!("route info format error");
|
||||
continue;
|
||||
}
|
||||
let cidr = route_info[0];
|
||||
let gateway = route_info[1].parse::<Ipv4Addr>().unwrap();
|
||||
let ip_and_mask: Vec<_> = cidr.split("/").collect();
|
||||
if ip_and_mask.len() != 2 {
|
||||
println!("route info ip/bit error");
|
||||
continue;
|
||||
}
|
||||
let ip = ip_and_mask[0].parse::<Ipv4Addr>().unwrap();
|
||||
let maskbit = ip_and_mask[1].parse::<u8>().unwrap();
|
||||
result.push((
|
||||
u32::from_be_bytes(ip.octets()),
|
||||
net_bit_len_to_mask(maskbit),
|
||||
u32::from_be_bytes(gateway.octets()),
|
||||
));
|
||||
}
|
||||
result
|
||||
}
|
||||
@ -23,9 +23,11 @@ pub struct Sdlv6Info {
|
||||
pub struct SdlDevAddr {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub network_id: u32,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub net_addr: u32,
|
||||
#[prost(bytes = "vec", tag = "2")]
|
||||
pub mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub net_addr: u32,
|
||||
#[prost(uint32, tag = "4")]
|
||||
pub net_bit_len: u32,
|
||||
}
|
||||
/// tcp通讯消息
|
||||
@ -55,8 +57,8 @@ pub struct SdlRegisterSuperAck {
|
||||
pub dev_addr: ::core::option::Option<SdlDevAddr>,
|
||||
#[prost(bytes = "vec", tag = "2")]
|
||||
pub aes_key: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", tag = "3")]
|
||||
pub known_ips: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(map = "uint32, bytes", tag = "3")]
|
||||
pub known_macs: ::std::collections::HashMap<u32, ::prost::alloc::vec::Vec<u8>>,
|
||||
#[prost(uint32, tag = "4")]
|
||||
pub upgrade_type: u32,
|
||||
#[prost(string, optional, tag = "5")]
|
||||
@ -75,14 +77,14 @@ pub struct SdlRegisterSuperNak {
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct SdlQueryInfo {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub dst_ip: u32,
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub dst_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct SdlPeerInfo {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub dst_ip: u32,
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub dst_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(message, optional, tag = "2")]
|
||||
pub v4_info: ::core::option::Option<Sdlv4Info>,
|
||||
#[prost(message, optional, tag = "3")]
|
||||
@ -90,27 +92,33 @@ pub struct SdlPeerInfo {
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct SdlKnownIpEvent {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub struct SdlKnownMacEvent {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub ip: u32,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct SdlDropIpEvent {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub struct SdlDropMacEvent {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub ip: u32,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct SdlNatChangedEvent {
|
||||
#[prost(uint32, tag = "1")]
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub ip: u32,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct SdlSendRegisterEvent {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub dst_ip: u32,
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub dst_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub nat_ip: u32,
|
||||
#[prost(uint32, tag = "3")]
|
||||
@ -131,8 +139,8 @@ pub struct SdlChangeNetworkCommand {
|
||||
pub dev_addr: ::core::option::Option<SdlDevAddr>,
|
||||
#[prost(bytes = "vec", tag = "2")]
|
||||
pub aes_key: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", tag = "3")]
|
||||
pub known_ips: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(map = "uint32, bytes", tag = "3")]
|
||||
pub known_macs: ::std::collections::HashMap<u32, ::prost::alloc::vec::Vec<u8>>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
@ -165,11 +173,13 @@ pub struct SdlStunRequest {
|
||||
pub client_id: ::prost::alloc::string::String,
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub network_id: u32,
|
||||
#[prost(uint32, tag = "4")]
|
||||
pub ip: u32,
|
||||
#[prost(bytes = "vec", tag = "4")]
|
||||
pub mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub ip: u32,
|
||||
#[prost(uint32, tag = "6")]
|
||||
pub nat_type: u32,
|
||||
#[prost(message, optional, tag = "6")]
|
||||
#[prost(message, optional, tag = "7")]
|
||||
pub v6_info: ::core::option::Option<Sdlv6Info>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
@ -183,10 +193,10 @@ pub struct SdlStunReply {
|
||||
pub struct SdlData {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub network_id: u32,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub src_ip: u32,
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub dst_ip: u32,
|
||||
#[prost(bytes = "vec", tag = "2")]
|
||||
pub src_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", tag = "3")]
|
||||
pub dst_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bool, tag = "4")]
|
||||
pub is_p2p: bool,
|
||||
#[prost(uint32, tag = "5")]
|
||||
@ -199,20 +209,20 @@ pub struct SdlData {
|
||||
pub struct SdlRegister {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub network_id: u32,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub src_ip: u32,
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub dst_ip: u32,
|
||||
#[prost(bytes = "vec", tag = "2")]
|
||||
pub src_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", tag = "3")]
|
||||
pub dst_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct SdlRegisterAck {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub network_id: u32,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub src_ip: u32,
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub dst_ip: u32,
|
||||
#[prost(bytes = "vec", tag = "2")]
|
||||
pub src_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(bytes = "vec", tag = "3")]
|
||||
pub dst_mac: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
|
||||
@ -2,7 +2,15 @@ mod command;
|
||||
pub use command::*;
|
||||
|
||||
mod socks;
|
||||
use sdlan_sn_rs::utils::Mac;
|
||||
pub use socks::*;
|
||||
|
||||
mod pid_recorder;
|
||||
pub use pid_recorder::PidRecorder;
|
||||
|
||||
pub fn mac_to_string(mac: &Mac) -> String {
|
||||
format!(
|
||||
"[{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}]",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user