changed to new message.proto, and use Bytes for SDLData's data

This commit is contained in:
alex 2026-02-25 15:30:26 +08:00
parent c5b04eb843
commit 6f895c3404
12 changed files with 423 additions and 191 deletions

5
Cargo.lock generated
View File

@ -224,9 +224,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.11.0"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]]
name = "c2rust-bitfields"
@ -1868,6 +1868,7 @@ dependencies = [
name = "punchnet"
version = "1.0.0"
dependencies = [
"bytes",
"cargo-deb",
"crc",
"crc32fast",

View File

@ -28,6 +28,7 @@ tokio = { version = "1.38.0", features = ["full"] }
tokio-util = "0.7.11"
tracing = "0.1.40"
myactor = { git = "https://gitea.s5s8.com/rust/actor-rs.git" }
bytes = "1.11.1"
# rolling-file = { path = "../rolling-file" }
[target.'cfg(unix)'.dependencies]

View File

@ -1,5 +1,7 @@
syntax = "proto3";
package message;
//
message SDLV4Info {
@ -13,54 +15,101 @@ message SDLV6Info {
bytes v6 = 2;
}
//
message SDLDevAddr {
uint32 network_id = 1;
bytes mac = 2;
uint32 net_addr = 3;
uint32 net_bit_len = 4;
string network_domain = 5;
}
// super之间采用了quic协议通讯
// : <<Len:16, PacketType:8, Payload/binary>>
// tcp通讯消息
message SDLEmpty {
}
message SDLRegisterSuper {
message SDLWelcome {
uint32 version = 1;
string installed_channel = 2;
string client_id = 3;
SDLDevAddr dev_addr = 4;
string pub_key = 5;
string token = 6;
string network_code = 7;
string hostname = 8;
//
uint32 max_bidi_streams = 2;
//
uint32 max_packet_size = 3;
//
uint32 heartbeat_sec = 4;
}
// quic
message SDLEmpty {
uint32 pkt_id = 1;
}
// ,
message SDLRegisterSuper {
uint32 pkt_id = 1;
string client_id = 2;
// https请求分配了
// (network_id, mac, ip, mask_len, hostname)
uint32 network_id = 3;
bytes mac = 4;
uint32 ip = 5;
uint32 mask_len = 6;
string hostname = 7;
string pub_key = 8;
// 使http协议请求后端token或者账号密码登录时, access_token;
// RegisterSuper的时候 (access_token)
string access_token = 9;
}
// https的接口里面去完成
// quic去通讯session_token校验
message SDLRegisterSuperAck {
SDLDevAddr dev_addr = 1;
uint32 pkt_id = 1;
bytes aes_key = 2;
uint32 upgrade_type = 3;
optional string upgrade_prompt = 4;
optional string upgrade_address = 5;
bytes session_token = 3;
}
message SDLRegisterSuperNak {
uint32 error_code = 1;
string error_message = 2;
uint32 pkt_id = 1;
uint32 error_code = 2;
string error_message = 3;
}
//
message SDLQueryInfo {
bytes dst_mac = 1;
uint32 pkt_id = 1;
bytes dst_mac = 2;
}
message SDLPeerInfo {
bytes dst_mac = 1;
SDLV4Info v4_info = 2;
optional SDLV6Info v6_info = 3;
uint32 pkt_id = 1;
bytes dst_mac = 2;
SDLV4Info v4_info = 3;
optional SDLV6Info v6_info = 4;
}
// ARP查询相关
// arp请求是通过广播的形式获取到的macos这种tun的实现arp请求包的
// mac对应的ip地址的广
message SDLArpRequest {
uint32 pkt_id = 1;
uint32 target_ip = 2;
}
message SDLArpResponse {
uint32 pkt_id = 1;
uint32 target_ip = 2;
bytes target_mac = 3;
}
//
message SDLPolicyRequest {
uint32 pkt_id = 1;
uint32 src_identity_id = 2;
uint32 dst_identity_id = 3;
uint32 version = 4;
}
// quic通讯rules部分已经没有了长度限制
message SDLPolicyResponse {
uint32 pkt_id = 1;
uint32 src_identity_id = 2;
uint32 dst_identity_id = 3;
// ;
uint32 version = 4;
// 4+1+2
bytes rules = 5;
}
//
@ -82,30 +131,9 @@ message SDLNetworkShutdownEvent {
string message = 1;
}
//
message SDLChangeNetworkCommand {
SDLDevAddr dev_addr = 1;
bytes aes_key = 2;
}
message SDLCommandAck {
// status = true, status = false message是失败原因描述
bool status = 1;
optional string message = 2;
}
message SDLFlows {
//
uint32 forward_num = 1;
// p2p直接流量
uint32 p2p_num = 2;
//
uint32 inbound_num = 3;
}
// UDP通讯消息
// client和stun之间的心跳包super的udp之间的存活逻辑
message SDLStunRequest {
uint32 cookie = 1;
string client_id = 2;
@ -114,6 +142,7 @@ message SDLStunRequest {
uint32 ip = 5;
uint32 nat_type = 6;
optional SDLV6Info v6_info = 7;
bytes session_token = 8;
}
message SDLStunReply {
@ -127,8 +156,31 @@ message SDLData {
bool is_p2p = 4;
uint32 ttl = 5;
bytes data = 6;
bytes session_token = 7;
// https登录的时候
//
uint32 identity_id = 8;
}
//
message SDLStunProbe {
uint32 cookie = 1;
uint32 attr = 2;
// step是为了方便端上判断
uint32 step = 3;
}
message SDLStunProbeReply {
uint32 cookie = 1;
// step是为了方便端上判断
uint32 step = 2;
uint32 port = 3;
uint32 ip = 4;
}
// Node-Node之间的握手逻辑, udp传输的
message SDLRegister {
uint32 network_id = 1;
bytes src_mac = 2;
@ -139,17 +191,4 @@ message SDLRegisterAck {
uint32 network_id = 1;
bytes src_mac = 2;
bytes dst_mac = 3;
}
//
message SDLStunProbe {
uint32 cookie = 1;
uint32 attr = 2;
}
message SDLStunProbeReply {
uint32 cookie = 1;
uint32 port = 2;
uint32 ip = 3;
}

View File

@ -1,6 +1,7 @@
fn main() {
prost_build::Config::new()
.out_dir("src/pb")
.bytes(&[".message.SDLData.data"])
// .out_dir("../tcp_mock/pb")
.protoc_arg("--experimental_allow_proto3_optional")
.compile_protos(&["message.proto"], &["."])

View File

@ -109,7 +109,15 @@ async fn main() {
// exit(0);
}
*/
if let Err(e) = edge.start_without_feedback(cmd.token, cmd.network_code, None).await {
if let Err(e) = edge.start_without_feedback(
String::new(),
0,
&"".to_owned(),
0,
24,
0,
Some("".to_owned())
).await {
error!("failed to start: {:?}", e);
}

View File

@ -16,7 +16,7 @@ use crate::pb::{
encode_to_tcp_message, encode_to_udp_message, SdlEmpty, SdlStunProbe, SdlStunProbeReply,
};
use crate::tcp::{get_tcp_conn, NatType, PacketType, StunProbeAttr};
use crate::utils::{Socket};
use crate::utils::{Socket, create_or_load_mac};
use sdlan_sn_rs::peer::{IpSubnet, V6Info};
@ -79,8 +79,8 @@ pub async fn init_edge(
node_conf,
sock_v4,
sock_multicast,
token,
network_code,
// token,
// network_code,
privatekey,
tcp_pong.clone(),
start_stop,
@ -123,10 +123,48 @@ pub struct StartStopInfo {
pub pkt_id: Option<u32>,
}
pub struct StringToken<T>(RwLock<T>);
impl <T: Clone> StringToken<T> {
pub fn new(value: T) -> Self {
Self(RwLock::new(value))
}
pub fn get(&self) -> T {
self.0.read().unwrap().clone()
}
pub fn set(&self, token: T) {
*self.0.write().unwrap() = token;
}
}
pub struct IdentityID(AtomicU32);
impl IdentityID {
pub fn new(id: u32) -> Self {
Self(AtomicU32::new(id))
}
pub fn load(&self) -> u32 {
self.0.load(Ordering::Relaxed)
}
pub fn store(&self, id: u32) {
self.0.store(id, Ordering::Relaxed);
}
}
pub struct Node {
packet_id: AtomicU32,
pub network_id: AtomicU32,
pub network_domain: RwLock<String>,
pub identity_id: IdentityID,
pub access_token: StringToken<String>,
pub session_token: StringToken<Vec<u8>>,
pub hostname: RwLock<String>,
@ -139,8 +177,8 @@ pub struct Node {
pub connection_chan: Option<Sender<ConnectionInfo>>,
// user token info
pub _token: Mutex<String>,
pub network_code: Mutex<String>,
// pub _token: Mutex<String>,
// pub network_code: Mutex<String>,
pub device_config: DeviceConfig,
pub device: Iface,
@ -205,14 +243,33 @@ impl Node {
self.nat_type.lock().unwrap().clone()
}
pub async fn start_without_feedback(&self, token: String, network_code: String, hostname: Option<String>) -> Result<()> {
pub async fn start_without_feedback(
&self,
access_token: String,
network_id: u32,
network_domain: &String,
ip_net: u32,
ip_net_bit_len: u8,
identity_id: u32,
hostname: Option<String>
) -> Result<()> {
if let Some(host) = hostname {
let idfile = format!("{}/.host", get_base_dir());
let _ = save_to_file(&idfile, &host);
*self.hostname.write().unwrap() = host;
}
*self._token.lock().unwrap() = token;
*self.network_code.lock().unwrap() = network_code;
self.access_token.set(access_token);
self.device_config.ip.net_addr.store(ip_net, Ordering::Relaxed);
self.device_config.ip.net_bit_len.store(ip_net_bit_len, Ordering::Relaxed);
*self.device_config.mac.write().unwrap() = create_or_load_mac();
self.network_id.store(network_id, Ordering::Relaxed);
self.network_domain.write().unwrap().clone_from(network_domain);
// self.network_domain = network_domain;
self.identity_id.store(identity_id);
// *self._token.lock().unwrap() = token;
// *self.network_code.lock().unwrap() = network_code;
let _ = self
.start_stop_sender
.send(StartStopInfo {
@ -225,8 +282,17 @@ impl Node {
pub async fn start_with_feedback(
&self,
token: String,
network_code: String,
access_token: String,
network_id: u32,
network_domain: &String,
ip_net: u32,
ip_net_bit_len: u8,
identity_id: u32,
// token: String,
// network_code: String,
hostname: Option<String>,
timeout: Duration,
) -> Result<RegisterSuperFeedback> {
@ -235,8 +301,17 @@ impl Node {
let _ = save_to_file(&idfile, &host);
*self.hostname.write().unwrap() = host;
}
*self._token.lock().unwrap() = token;
*self.network_code.lock().unwrap() = network_code;
self.access_token.set(access_token);
self.device_config.ip.net_addr.store(ip_net, Ordering::Relaxed);
self.device_config.ip.net_bit_len.store(ip_net_bit_len, Ordering::Relaxed);
*self.device_config.mac.write().unwrap() = create_or_load_mac();
self.network_id.store(network_id, Ordering::Relaxed);
self.network_domain.write().unwrap().clone_from(network_domain);
self.identity_id.store(identity_id);
// *self._token.lock().unwrap() = token;
// *self.network_code.lock().unwrap() = network_code;
let (tx, rx) = oneshot::channel();
let id = self.get_next_packet_id();
self.packet_id_match.insert(id, tx);
@ -265,7 +340,8 @@ impl Node {
}
pub async fn stop(&self) {
*self._token.lock().unwrap() = "".to_owned();
// *self._token.lock().unwrap() = "".to_owned();
self.session_token.set(vec![]);
let _ = self
.start_stop_sender
.send(StartStopInfo {
@ -281,8 +357,8 @@ impl Node {
sock: Socket,
multicast_sock: Option<Socket>,
// tcpsock: TCPSocket,
token: &str,
network_code: &str,
// token: &str,
// network_code: &str,
private: RsaPrivateKey,
tcp_pong: Arc<AtomicU64>,
start_stop: Sender<StartStopInfo>,
@ -304,10 +380,16 @@ impl Node {
network_id: AtomicU32::new(0),
hostname: RwLock::new(hostname),
network_domain: RwLock::new(String::new()),
udp_sock_for_dns: udpsock_for_dns,
_token: Mutex::new(token.to_owned()),
network_code: Mutex::new(network_code.to_owned()),
identity_id: IdentityID::new(0),
access_token: StringToken::new(String::new()),
session_token: StringToken::new(Vec::new()),
// _token: Mutex::new(token.to_owned()),
// network_code: Mutex::new(network_code.to_owned()),
start_stop_sender: start_stop,
connection_chan: connecting_chan,
@ -515,6 +597,7 @@ impl Node {
let probe = SdlStunProbe {
attr: msgattr as u32,
cookie,
step: 0,
};
// println!("==> sending probe request: {:?}", probe);

View File

@ -1132,6 +1132,7 @@ async fn send_query_peer(eee: &Node, dst_mac: Mac) -> Result<()> {
}
let query = SdlQueryInfo {
dst_mac: Vec::from(dst_mac),
pkt_id: 0,
};
let Ok(content) = encode_to_tcp_message(

View File

@ -221,6 +221,8 @@ impl TunTapPacketHandler for Iface {
if let Some(eth) = headers.link {
if let Some(hdr) = eth.ethernet2() {
use bytes::Bytes;
if let Some(ip) = headers.net {
match ip {
etherparse::NetHeaders::Ipv4(ipv4, _) => {
@ -251,13 +253,16 @@ impl TunTapPacketHandler for Iface {
error!("failed to encrypt packet request");
return Ok(());
};
let data_bytes = Bytes::from(encrypted);
let data = SdlData {
is_p2p: true,
network_id: edge.network_id.load(Ordering::Relaxed),
ttl: SDLAN_DEFAULT_TTL as u32,
src_mac: Vec::from(edge.device_config.get_mac()),
dst_mac: Vec::from(target),
data: Vec::from(encrypted),
data: data_bytes,
identity_id: edge.identity_id.load(),
session_token: edge.session_token.get(),
};
let msg = encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();

View File

@ -1,5 +1,6 @@
use std::sync::atomic::Ordering;
use bytes::Bytes;
use dashmap::DashMap;
use once_cell::sync::OnceCell;
use sdlan_sn_rs::{
@ -91,13 +92,16 @@ impl ArpWaitList {
error!("failed to encrypt packet request");
return;
};
let data_bytes = Bytes::from(encrypted);
let data = SdlData {
is_p2p: true,
network_id,
ttl: SDLAN_DEFAULT_TTL as u32,
src_mac: Vec::from(src_mac),
dst_mac: Vec::from(mac),
data: Vec::from(encrypted),
data: data_bytes,
identity_id: edge.identity_id.load(),
session_token: edge.session_token.get(),
};
let msg = encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
send_packet_to_net(edge, mac, &msg, pkt_size as u64).await;

View File

@ -17,83 +17,148 @@ pub struct Sdlv6Info {
#[prost(bytes = "vec", tag = "2")]
pub v6: ::prost::alloc::vec::Vec<u8>,
}
/// 设备网络地址信息
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlDevAddr {
pub struct SdlWelcome {
#[prost(uint32, tag = "1")]
pub network_id: u32,
#[prost(bytes = "vec", tag = "2")]
pub mac: ::prost::alloc::vec::Vec<u8>,
pub version: u32,
/// 服务器允许的最大双向流
#[prost(uint32, tag = "2")]
pub max_bidi_streams: u32,
/// 服务器允许的最大包
#[prost(uint32, tag = "3")]
pub net_addr: u32,
pub max_packet_size: u32,
/// 心跳包的间隔
#[prost(uint32, tag = "4")]
pub net_bit_len: u32,
#[prost(string, tag = "5")]
pub network_domain: ::prost::alloc::string::String,
pub heartbeat_sec: u32,
}
/// tcp通讯消息
/// quic 通讯消息
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlEmpty {}
pub struct SdlEmpty {
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
}
/// 这里修改成了扁平的结构, 否则有些字段不好找放的位置
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlRegisterSuper {
#[prost(uint32, tag = "1")]
pub version: u32,
pub pkt_id: u32,
#[prost(string, tag = "2")]
pub installed_channel: ::prost::alloc::string::String,
#[prost(string, tag = "3")]
pub client_id: ::prost::alloc::string::String,
#[prost(message, optional, tag = "4")]
pub dev_addr: ::core::option::Option<SdlDevAddr>,
#[prost(string, tag = "5")]
pub pub_key: ::prost::alloc::string::String,
#[prost(string, tag = "6")]
pub token: ::prost::alloc::string::String,
/// 网络地址信息已经有https请求分配了
/// 注册的时候需要带上(network_id, mac, ip, mask_len, hostname)
#[prost(uint32, tag = "3")]
pub network_id: 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 mask_len: u32,
#[prost(string, tag = "7")]
pub network_code: ::prost::alloc::string::String,
#[prost(string, tag = "8")]
pub hostname: ::prost::alloc::string::String,
#[prost(string, tag = "8")]
pub pub_key: ::prost::alloc::string::String,
/// 客户端使用http协议请求后端通过token或者账号密码登录时, 统一返回一个access_token;
/// RegisterSuper的时候验证凭证是否合法 (access_token)
#[prost(string, tag = "9")]
pub access_token: ::prost::alloc::string::String,
}
/// 客户端的升级逻辑在https的接口里面去完成
/// 部分逻辑会脱离quic去通讯增加session_token校验
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlRegisterSuperAck {
#[prost(message, optional, tag = "1")]
pub dev_addr: ::core::option::Option<SdlDevAddr>,
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
#[prost(bytes = "vec", tag = "2")]
pub aes_key: ::prost::alloc::vec::Vec<u8>,
#[prost(uint32, tag = "3")]
pub upgrade_type: u32,
#[prost(string, optional, tag = "4")]
pub upgrade_prompt: ::core::option::Option<::prost::alloc::string::String>,
#[prost(string, optional, tag = "5")]
pub upgrade_address: ::core::option::Option<::prost::alloc::string::String>,
#[prost(bytes = "vec", tag = "3")]
pub session_token: ::prost::alloc::vec::Vec<u8>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlRegisterSuperNak {
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
#[prost(uint32, tag = "2")]
pub error_code: u32,
#[prost(string, tag = "2")]
#[prost(string, tag = "3")]
pub error_message: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlQueryInfo {
#[prost(bytes = "vec", tag = "1")]
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
#[prost(bytes = "vec", tag = "2")]
pub dst_mac: ::prost::alloc::vec::Vec<u8>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlPeerInfo {
#[prost(bytes = "vec", tag = "1")]
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
#[prost(bytes = "vec", tag = "2")]
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")]
pub v4_info: ::core::option::Option<Sdlv4Info>,
#[prost(message, optional, tag = "4")]
pub v6_info: ::core::option::Option<Sdlv6Info>,
}
/// ARP查询相关
/// 真实的arp请求是通过广播的形式获取到的但是针对于macos这种tun的实现是能够分析出arp请求包的
/// 对于当前网络来说服务端是知道mac对应的ip地址的因此没有必要广播直接通过服务器端返回
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlArpRequest {
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
#[prost(uint32, tag = "2")]
pub target_ip: u32,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlArpResponse {
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
#[prost(uint32, tag = "2")]
pub target_ip: u32,
#[prost(bytes = "vec", tag = "3")]
pub target_mac: ::prost::alloc::vec::Vec<u8>,
}
/// 权限请求查询相关
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlPolicyRequest {
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
#[prost(uint32, tag = "2")]
pub src_identity_id: u32,
#[prost(uint32, tag = "3")]
pub dst_identity_id: u32,
#[prost(uint32, tag = "4")]
pub version: u32,
}
/// 基于quic通讯rules部分已经没有了长度限制
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlPolicyResponse {
#[prost(uint32, tag = "1")]
pub pkt_id: u32,
#[prost(uint32, tag = "2")]
pub src_identity_id: u32,
#[prost(uint32, tag = "3")]
pub dst_identity_id: u32,
/// 版本号,客户端需要比较版本号确定是否覆盖; 请求端自己去管理版本号,服务端只是原样回写
#[prost(uint32, tag = "4")]
pub version: u32,
/// 4+1+2 的稀疏序列化规则
#[prost(bytes = "vec", tag = "5")]
pub rules: ::prost::alloc::vec::Vec<u8>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlNatChangedEvent {
@ -122,36 +187,7 @@ pub struct SdlNetworkShutdownEvent {
#[prost(string, tag = "1")]
pub message: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlChangeNetworkCommand {
#[prost(message, optional, tag = "1")]
pub dev_addr: ::core::option::Option<SdlDevAddr>,
#[prost(bytes = "vec", tag = "2")]
pub aes_key: ::prost::alloc::vec::Vec<u8>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlCommandAck {
/// status = true, 表示成功status = false 表示失败message是失败原因描述
#[prost(bool, tag = "1")]
pub status: bool,
#[prost(string, optional, tag = "2")]
pub message: ::core::option::Option<::prost::alloc::string::String>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlFlows {
/// 服务器转发流量
#[prost(uint32, tag = "1")]
pub forward_num: u32,
/// p2p直接流量
#[prost(uint32, tag = "2")]
pub p2p_num: u32,
/// 接收的流量
#[prost(uint32, tag = "3")]
pub inbound_num: u32,
}
/// client和stun之间的心跳包客户端需要和super的udp之间的存活逻辑
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlStunRequest {
@ -169,6 +205,8 @@ pub struct SdlStunRequest {
pub nat_type: u32,
#[prost(message, optional, tag = "7")]
pub v6_info: ::core::option::Option<Sdlv6Info>,
#[prost(bytes = "vec", tag = "8")]
pub session_token: ::prost::alloc::vec::Vec<u8>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -189,8 +227,38 @@ pub struct SdlData {
pub is_p2p: bool,
#[prost(uint32, tag = "5")]
pub ttl: u32,
#[prost(bytes = "vec", tag = "6")]
pub data: ::prost::alloc::vec::Vec<u8>,
#[prost(bytes = "bytes", tag = "6")]
pub data: ::prost::bytes::Bytes,
#[prost(bytes = "vec", tag = "7")]
pub session_token: ::prost::alloc::vec::Vec<u8>,
/// 端通过https登录的时候服务端会分配该端对应的权限标识
/// 后续的请求过程中需要带上这个值,对端通过这个值要判断对数据包是否放行
#[prost(uint32, tag = "8")]
pub identity_id: u32,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlStunProbe {
#[prost(uint32, tag = "1")]
pub cookie: u32,
#[prost(uint32, tag = "2")]
pub attr: u32,
/// 增加step是为了方便端上判断收到的请求和响应之间的映射关系服务器端原样返回
#[prost(uint32, tag = "3")]
pub step: u32,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlStunProbeReply {
#[prost(uint32, tag = "1")]
pub cookie: u32,
/// 增加step是为了方便端上判断收到的请求和响应之间的映射关系服务器端原样返回
#[prost(uint32, tag = "2")]
pub step: u32,
#[prost(uint32, tag = "3")]
pub port: u32,
#[prost(uint32, tag = "4")]
pub ip: u32,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -212,21 +280,3 @@ pub struct SdlRegisterAck {
#[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 SdlStunProbe {
#[prost(uint32, tag = "1")]
pub cookie: u32,
#[prost(uint32, tag = "2")]
pub attr: u32,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SdlStunProbeReply {
#[prost(uint32, tag = "1")]
pub cookie: u32,
#[prost(uint32, tag = "2")]
pub port: u32,
#[prost(uint32, tag = "3")]
pub ip: u32,
}

View File

@ -25,7 +25,7 @@ use tracing::error;
use crate::config::{NULL_MAC, TCP_PING_TIME};
use crate::network::{Node, RegisterSuperFeedback, StartStopInfo, check_peer_registration_needed, handle_packet_peer_info};
use crate::pb::{SdlDevAddr, SdlRegisterSuper, SdlRegisterSuperAck, SdlRegisterSuperNak, SdlSendRegisterEvent, SdlStunRequest, Sdlv6Info, encode_to_tcp_message, encode_to_udp_message};
use crate::pb::{SdlRegisterSuper, SdlRegisterSuperAck, SdlRegisterSuperNak, SdlSendRegisterEvent, SdlStunRequest, Sdlv6Info, encode_to_tcp_message, encode_to_udp_message};
use crate::tcp::{EventType, NakMsgCode, NatType, PacketType, read_a_packet};
use crate::utils::send_to_sock;
use crate::{ConnectionInfo, ConnectionState, get_edge};
@ -61,20 +61,24 @@ async fn handle_tcp_message(msg: SdlanTcp) {
error!("failed to rsa decrypt aes key");
return;
};
/*
let Some(dev) = ack.dev_addr else {
error!("no dev_addr is specified");
return;
};
*/
let ip = ip_to_string(&dev.net_addr);
let ip = ip_to_string(&edge.device_config.get_ip());
// debug!("aes key is {:?}, ip is {}/{}", aes, ip, dev.net_bit_len,);
println!("assigned ip: {}", ip);
let hostname = edge.hostname.read().unwrap().clone();
println!("network is: {}.{}", hostname, dev.network_domain);
// println!("network is: {}.{}", hostname, dev.network_domain);
/*
edge.device_config
.ip
.net_addr
.store(dev.net_addr, Ordering::Relaxed);
*/
if let Some(ref chan) = edge.connection_chan {
let _ = chan.send(ConnectionInfo::IPInfo(ip)).await;
}
@ -85,12 +89,15 @@ async fn handle_tcp_message(msg: SdlanTcp) {
};
*/
// *edge.device_config.mac.write().unwrap() = mac;
/*
edge.device_config
.ip
.net_bit_len
.store(dev.net_bit_len as u8, Ordering::Relaxed);
edge.device.reload_config(&edge.device_config, &dev.network_domain);
edge.network_id.store(dev.network_id, Ordering::Relaxed);
*/
// edge.device.reload_config(&edge.device_config, &dev.network_domain);
edge.device.reload_config(&edge.device_config, &edge.network_domain.read().unwrap().clone());
edge.set_authorized(true, aes);
send_stun_request(edge).await;
@ -263,6 +270,7 @@ pub async fn send_stun_request(eee: &Node) {
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),
@ -293,8 +301,9 @@ async fn on_connected_callback<'a>(stream: &'a mut tokio::net::TcpStream, pkt_id
let edge = get_edge();
// let installed_channel = install_channel.to_owned();
let token = edge._token.lock().unwrap().clone();
let code = edge.network_code.lock().unwrap().clone();
// let token = edge._token.lock().unwrap().clone();
// let code = edge.network_code.lock().unwrap().clone();
// let edge = get_edge();
// let edge = get_edge();
// let token = args.token.clone();
@ -309,20 +318,16 @@ async fn on_connected_callback<'a>(stream: &'a mut tokio::net::TcpStream, pkt_id
}
}
let register_super = SdlRegisterSuper {
version: 1,
installed_channel: edge.install_channel.clone(),
mac: Vec::from(edge.device_config.get_mac()),
pkt_id: edge.get_next_packet_id(),
network_id: edge.network_id.load(Ordering::Relaxed),
ip: edge.device_config.get_ip(),
mask_len: edge.device_config.get_net_bit() as u32,
access_token: edge.access_token.get(),
// installed_channel,
client_id: edge.config.node_uuid.clone(),
dev_addr: Some(SdlDevAddr {
mac: Vec::from(edge.device_config.get_mac()),
net_addr: 0,
network_id: 0,
net_bit_len: 0,
network_domain: "".to_owned(),
}),
pub_key: edge.rsa_pubkey.clone(),
token,
network_code: code,
hostname: edge.hostname.read().unwrap().clone(),
};
// debug!("send register super: {:?}", register_super);

View File

@ -1,12 +1,16 @@
mod command;
use std::{fs::OpenOptions, io::Write, path::Path};
pub use command::*;
mod socks;
use rand::Rng;
use sdlan_sn_rs::utils::Mac;
use sdlan_sn_rs::utils::{Mac, Result, SDLanError, save_to_file};
pub use socks::*;
use crate::get_base_dir;
mod pid_recorder;
// pub const CRC_HASH: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_XFER);
@ -17,6 +21,36 @@ pub fn caculate_crc(data: &[u8]) -> u32 {
res
}
pub fn create_or_load_mac() -> Mac {
let path = format!("{}/.mac", get_base_dir());
if let Ok(content) = std::fs::read(&path) {
if content.len() == 6 {
let mut mac = [0; 6];
mac.copy_from_slice(&content);
return mac;
}
}
let mac = generate_mac_address();
let _ = save_to_file_binary(&path, &mac);
mac
}
pub fn save_to_file_binary(idfile: &str, content: &[u8]) -> Result<()> {
if idfile.len() == 0 {
return Err(SDLanError::IOError("file is empty".to_owned()));
}
let filepath = Path::new(idfile);
OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(filepath)?
.write_all(content)?;
Ok(())
}
pub fn mac_to_string(mac: &Mac) -> String {
format!(
"[{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}]",