moved the sdlan-sn and sdlan to the outer workspace
This commit is contained in:
parent
e2aa6c9eb4
commit
c12d62e4b1
13
Cargo.toml
13
Cargo.toml
@ -7,11 +7,10 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aes = "0.8.4"
|
aes = "0.8.4"
|
||||||
anyhow = "1.0.79"
|
|
||||||
byteorder = "1.5.0"
|
byteorder = "1.5.0"
|
||||||
cbc = "0.1.2"
|
cbc = "0.1.2"
|
||||||
dashmap = "5.5.3"
|
dashmap = "5.5.3"
|
||||||
lazy_static = "1.4.0"
|
# lazy_static = "1.4.0"
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
rolling-file = { git = "https://git.asxalex.pw/rust/rolling-file" }
|
rolling-file = { git = "https://git.asxalex.pw/rust/rolling-file" }
|
||||||
@ -19,13 +18,9 @@ rsa = "0.9.6"
|
|||||||
serde = { version = "1.0.196", features = ["derive"] }
|
serde = { version = "1.0.196", features = ["derive"] }
|
||||||
serde_json = "1.0.113"
|
serde_json = "1.0.113"
|
||||||
serde_repr = "0.1.18"
|
serde_repr = "0.1.18"
|
||||||
sqlx = { version = "0.7.3", features = [
|
sqlx = "0.7.3"
|
||||||
"sqlx-mysql",
|
#structopt = "0.3.26"
|
||||||
"mysql",
|
|
||||||
"runtime-tokio",
|
|
||||||
] }
|
|
||||||
structopt = "0.3.26"
|
|
||||||
tokio = { version = "1.36.0", features = ["full"] }
|
tokio = { version = "1.36.0", features = ["full"] }
|
||||||
tracing = "0.1.40"
|
#tracing = "0.1.40"
|
||||||
tracing-appender = "0.2.3"
|
tracing-appender = "0.2.3"
|
||||||
uuid = { version = "1.7.0", features = ["v4"] }
|
uuid = { version = "1.7.0", features = ["v4"] }
|
||||||
|
|||||||
@ -1,63 +0,0 @@
|
|||||||
#![allow(unused)]
|
|
||||||
|
|
||||||
use sdlan_sn_rs::peer::Peer;
|
|
||||||
|
|
||||||
use dashmap::DashMap;
|
|
||||||
use std::sync::atomic::Ordering;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::{Duration, Instant};
|
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
static ref DASH: DashMap<String, Arc<Peer>> = DashMap::new();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
let numbers = 1000000;
|
|
||||||
let number_of_routine = 400;
|
|
||||||
|
|
||||||
let start = Instant::now();
|
|
||||||
for i in 0..numbers {
|
|
||||||
let id = i.to_string();
|
|
||||||
let peer = Arc::new(Peer::new(&id));
|
|
||||||
DASH.insert(id, peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("insert {} record elapsed: {:?}", numbers, start.elapsed());
|
|
||||||
|
|
||||||
let mut handlers = vec![];
|
|
||||||
let start = Instant::now();
|
|
||||||
for i in 0..number_of_routine {
|
|
||||||
let handler = tokio::spawn(async move {
|
|
||||||
for j in 0..numbers {
|
|
||||||
// let info = DASH.get(&j.to_string()).unwrap().clone();
|
|
||||||
let info = DASH.get(&j.to_string()).unwrap();
|
|
||||||
info.last_seen.fetch_add(1, Ordering::Relaxed);
|
|
||||||
// println!("{j}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
handlers.push(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
for handler in handlers {
|
|
||||||
let v = handler.await;
|
|
||||||
}
|
|
||||||
println!(
|
|
||||||
"{}x{} times add elapsed: {:?}",
|
|
||||||
number_of_routine,
|
|
||||||
numbers,
|
|
||||||
start.elapsed()
|
|
||||||
);
|
|
||||||
for i in 0..10 {
|
|
||||||
println!(
|
|
||||||
"{:?}",
|
|
||||||
DASH.get(&i.to_string())
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
.last_seen
|
|
||||||
.load(Ordering::Relaxed)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
pub const DEFAULT_MIN_AUTO_IP_NET: &'static str = "10.128.0.0";
|
|
||||||
pub const DEFAULT_MAX_AUTO_IP_NET: &'static str = "10.255.255.0";
|
|
||||||
pub const DEFAULT_IP_NET_BIT_LEN: u8 = 24;
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
use sdlan_sn_rs::log;
|
|
||||||
use sdlan_sn_rs::packet;
|
|
||||||
use sdlan_sn_rs::utils::Result;
|
|
||||||
use tracing::{debug, error};
|
|
||||||
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
//use std::io::Read;
|
|
||||||
use std::net::SocketAddr;
|
|
||||||
use std::time::Duration;
|
|
||||||
use tokio::net::UdpSocket;
|
|
||||||
|
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
mod config;
|
|
||||||
mod models;
|
|
||||||
mod utils;
|
|
||||||
|
|
||||||
use models::create_network;
|
|
||||||
use models::init_db_pool;
|
|
||||||
|
|
||||||
use utils::license_ok;
|
|
||||||
|
|
||||||
async fn client(address: &str) -> Result<()> {
|
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0").await?;
|
|
||||||
let id = "Dejavu";
|
|
||||||
let cmn = packet::Common {
|
|
||||||
version: 1,
|
|
||||||
id,
|
|
||||||
ttl: 128,
|
|
||||||
pc: packet::PacketType::PKTRegisterSuper,
|
|
||||||
flags: 0x0200,
|
|
||||||
};
|
|
||||||
let value = cmn.encode();
|
|
||||||
loop {
|
|
||||||
socket.send_to(&value, address).await?;
|
|
||||||
tokio::time::sleep(Duration::from_millis(5000)).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<()> {
|
|
||||||
// init log
|
|
||||||
let _guard = log::init_log();
|
|
||||||
debug!("main starts here");
|
|
||||||
|
|
||||||
// check license
|
|
||||||
license_ok()?;
|
|
||||||
|
|
||||||
// parse command line argument
|
|
||||||
let args = utils::CommandLine::from_args();
|
|
||||||
debug!("args: {:?}", args);
|
|
||||||
// check the argument
|
|
||||||
let _: Ipv4Addr = args.address.parse().expect("invalid address found");
|
|
||||||
|
|
||||||
// init database
|
|
||||||
init_db_pool().await?;
|
|
||||||
|
|
||||||
create_network("测试network").await?;
|
|
||||||
|
|
||||||
let server = format!("{}:{}", args.address, args.port);
|
|
||||||
let cloned_server = server.clone();
|
|
||||||
let listener = UdpSocket::bind(server).await?;
|
|
||||||
|
|
||||||
let supernode = utils::SuperNode::new(listener, args.port);
|
|
||||||
utils::init_supernode(supernode).expect("failed to init supernode");
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
|
||||||
client(&cloned_server).await.unwrap();
|
|
||||||
});
|
|
||||||
|
|
||||||
let listener = utils::get_supernode();
|
|
||||||
loop {
|
|
||||||
// let mut buffer = [0; 2048];
|
|
||||||
let mut buffer = vec![0; 2048];
|
|
||||||
// let mut data = Vec::with_capacity(2048);
|
|
||||||
let (n, addr) = listener.sock.recv_from(&mut buffer).await?;
|
|
||||||
buffer.truncate(n);
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
|
||||||
if let Err(e) = handle_packet(&buffer, addr).await {
|
|
||||||
error!("failed to handle packet: {:?}", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_packet(pkt: &[u8], _: SocketAddr) -> Result<()> {
|
|
||||||
let common = packet::Common::from_slice(pkt)?;
|
|
||||||
println!("common: {:?}", common);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
-- Add migration script here
|
|
||||||
CREATE TABLE IF NOT EXISTS network (
|
|
||||||
id bigint auto_increment primary key,
|
|
||||||
uuid CHAR(32) NOT NULL,
|
|
||||||
name VARCHAR(128) NOT NULL default "",
|
|
||||||
is_fedration TINYINT(1) NOT NULL default 0,
|
|
||||||
enabled TINYINT(1) NOT NULL default 1,
|
|
||||||
network_pass VARCHAR(64) NOT NULL,
|
|
||||||
header_pass VARCHAR(64) NOT NULL,
|
|
||||||
net_addr INT UNSIGNED NOT NULL,
|
|
||||||
net_bit_len TINYINT UNSIGNED NOT NULL
|
|
||||||
);
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
use once_cell::sync::OnceCell;
|
|
||||||
use sdlan_sn_rs::utils::{gen_uuid, Result, SDLanError};
|
|
||||||
use sqlx::mysql::{MySqlPool, MySqlPoolOptions};
|
|
||||||
|
|
||||||
use crate::utils::Network;
|
|
||||||
|
|
||||||
const url: &'static str = "mysql://sdlan:sdlan-pass@localhost:3306/sdlan";
|
|
||||||
|
|
||||||
static DBPOOL: OnceCell<MySqlPool> = OnceCell::new();
|
|
||||||
|
|
||||||
pub async fn init_db_pool() -> Result<()> {
|
|
||||||
let pool = MySqlPoolOptions::new().connect(url).await?;
|
|
||||||
if let Err(_) = DBPOOL.set(pool) {
|
|
||||||
return Err(SDLanError::NormalError("init db pool failed"));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_db_pool() -> &'static MySqlPool {
|
|
||||||
DBPOOL.get().expect("db pool has not been initialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_network() -> Result<Vec<Network>> {
|
|
||||||
let pool = get_db_pool();
|
|
||||||
let mut res =
|
|
||||||
sqlx::query_as::<sqlx::mysql::MySql, Network>("select * from network where id = 2")
|
|
||||||
.fetch_all(pool)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
for r in res.iter_mut() {
|
|
||||||
r.edges.insert("hello".to_string());
|
|
||||||
println!("network is {:?}", r);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn create_network(name: &str) -> Result<String> {
|
|
||||||
let pool = get_db_pool();
|
|
||||||
let uuid = gen_uuid();
|
|
||||||
let networkpass = gen_uuid();
|
|
||||||
let headerpass = gen_uuid();
|
|
||||||
let res = sqlx::query(r#"insert into network (`uuid`, `name`, `network_pass`, `header_pass`, `net_addr`, `net_bit_len`) values (?,?,?,?,?,?);"#)
|
|
||||||
.bind(&uuid)
|
|
||||||
.bind(name)
|
|
||||||
.bind(networkpass)
|
|
||||||
.bind(headerpass)
|
|
||||||
.bind(0)
|
|
||||||
.bind(0)
|
|
||||||
.execute(pool).await?;
|
|
||||||
Ok(uuid)
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
use sdlan_sn_rs::utils::Result;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use tracing::error;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct LicenseInfo<'a> {
|
|
||||||
// 由谁颁发的
|
|
||||||
#[serde(rename = "from")]
|
|
||||||
from: &'a str,
|
|
||||||
// 颁发给谁的
|
|
||||||
#[serde(rename = "to")]
|
|
||||||
to: &'a str,
|
|
||||||
// 有效起始时间
|
|
||||||
#[serde(rename = "starts")]
|
|
||||||
starts: i64,
|
|
||||||
// 有效结束时间
|
|
||||||
#[serde(rename = "ends")]
|
|
||||||
ends: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn license_ok() -> Result<()> {
|
|
||||||
// TODO: check license
|
|
||||||
error!("license expired");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
mod sn;
|
|
||||||
pub use sn::*;
|
|
||||||
|
|
||||||
mod license;
|
|
||||||
pub use license::*;
|
|
||||||
|
|
||||||
mod params;
|
|
||||||
pub use params::*;
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
#[derive(StructOpt, Debug)]
|
|
||||||
pub struct CommandLine {
|
|
||||||
/// fedration, other sn
|
|
||||||
#[structopt(short = "f", long = "fedration", default_value = "")]
|
|
||||||
pub fedration: String,
|
|
||||||
#[structopt(short = "p", long = "port", default_value = "7655")]
|
|
||||||
pub port: u16,
|
|
||||||
#[structopt(short = "a", long = "addr", default_value = "0.0.0.0")]
|
|
||||||
pub address: String,
|
|
||||||
}
|
|
||||||
@ -1,136 +0,0 @@
|
|||||||
use dashmap::{DashMap, DashSet};
|
|
||||||
use sdlan_sn_rs::peer::IpSubnet;
|
|
||||||
use sdlan_sn_rs::utils::gen_uuid;
|
|
||||||
use sdlan_sn_rs::utils::MyDashMap;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::Serialize;
|
|
||||||
use sqlx::prelude::FromRow;
|
|
||||||
use tokio::net::UdpSocket;
|
|
||||||
|
|
||||||
use crate::config;
|
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
|
||||||
|
|
||||||
use sdlan_sn_rs::utils::{Result, SDLanError};
|
|
||||||
|
|
||||||
use once_cell::sync::OnceCell;
|
|
||||||
|
|
||||||
static SN: OnceCell<SuperNode> = OnceCell::new();
|
|
||||||
|
|
||||||
pub fn init_supernode(sn: SuperNode) -> Result<()> {
|
|
||||||
if let Err(_) = SN.set(sn) {
|
|
||||||
return Err(SDLanError::NormalError("initialize sn error"));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_supernode() -> &'static SuperNode {
|
|
||||||
SN.get().expect("Supernode has not been initialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SuperNode {
|
|
||||||
// supernode 启动时间
|
|
||||||
pub start_time: u64,
|
|
||||||
// 是否以daemon,后台运行。
|
|
||||||
pub daemon: bool,
|
|
||||||
|
|
||||||
// 本地监听的udp端口号
|
|
||||||
pub local_port: u16,
|
|
||||||
|
|
||||||
// 该SuperNode包含的所有的网络
|
|
||||||
// 在云端创建或者删除网络的时候,需要通知sn修改这个网络信息
|
|
||||||
pub networks: MyDashMap<Network>,
|
|
||||||
|
|
||||||
/// 把所有其他的supernode放在这个fedration里面,
|
|
||||||
/// 在广播或者收到消息发现本地不存在这个目标数据包的时候,
|
|
||||||
/// 需要把数据包广播到这个fedration中。
|
|
||||||
pub fedration: Network,
|
|
||||||
|
|
||||||
/// pending网络,所有未授权的放到这个网络里面
|
|
||||||
/// 当某个SN收到来自客户端的信息的时候,需要把客户端加到这个pending
|
|
||||||
/// 在数据库中保存一条记录,并且在redis中记录一条信息,表明这个客户端
|
|
||||||
/// 在我这个Supernode上
|
|
||||||
pub pending: Network,
|
|
||||||
|
|
||||||
pub ip_range: AutoIpAssign,
|
|
||||||
|
|
||||||
pub sock: UdpSocket,
|
|
||||||
|
|
||||||
pub auth_key: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SuperNode {
|
|
||||||
pub fn new(sock: UdpSocket, localport: u16) -> Self {
|
|
||||||
let now = SystemTime::now();
|
|
||||||
println!("now: {:?}", now);
|
|
||||||
let start_time = now
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.expect("time went backwards")
|
|
||||||
.as_secs();
|
|
||||||
|
|
||||||
let startip: u32 = config::DEFAULT_MIN_AUTO_IP_NET
|
|
||||||
.parse::<Ipv4Addr>()
|
|
||||||
.unwrap()
|
|
||||||
.into();
|
|
||||||
let endip: u32 = config::DEFAULT_MAX_AUTO_IP_NET
|
|
||||||
.parse::<Ipv4Addr>()
|
|
||||||
.unwrap()
|
|
||||||
.into();
|
|
||||||
Self {
|
|
||||||
start_time,
|
|
||||||
daemon: false,
|
|
||||||
local_port: localport,
|
|
||||||
networks: MyDashMap::new(),
|
|
||||||
fedration: Network::new("*fedration", gen_uuid(), true, 0, 0),
|
|
||||||
pending: Network::new("*pending", gen_uuid(), false, 0, 0),
|
|
||||||
ip_range: AutoIpAssign {
|
|
||||||
start_ip: IpSubnet::new(startip, config::DEFAULT_IP_NET_BIT_LEN),
|
|
||||||
end_ip: IpSubnet::new(endip, config::DEFAULT_IP_NET_BIT_LEN),
|
|
||||||
},
|
|
||||||
sock,
|
|
||||||
auth_key: String::from("encrypt!"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AutoIpAssign {
|
|
||||||
pub start_ip: IpSubnet,
|
|
||||||
pub end_ip: IpSubnet,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, FromRow, Debug)]
|
|
||||||
pub struct Network {
|
|
||||||
pub uuid: String,
|
|
||||||
pub name: String,
|
|
||||||
pub is_fedration: bool,
|
|
||||||
pub enabled: bool,
|
|
||||||
pub network_pass: String,
|
|
||||||
pub header_pass: String,
|
|
||||||
#[sqlx(flatten)]
|
|
||||||
pub auto_ip_net: IpSubnet,
|
|
||||||
// 这个网络下面的节点,ip到peer uuid
|
|
||||||
// pub edges: DashMap<u32, String>,
|
|
||||||
#[serde(skip)]
|
|
||||||
#[sqlx(skip)]
|
|
||||||
pub edges: DashSet<String>,
|
|
||||||
#[serde(skip)]
|
|
||||||
#[sqlx(skip)]
|
|
||||||
pub ip_to_edge_id: DashMap<u32, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Network {
|
|
||||||
fn new(name: &str, id: String, is_fedration: bool, ipnet: u32, ipnet_bitlen: u8) -> Self {
|
|
||||||
Self {
|
|
||||||
name: name.to_string(),
|
|
||||||
uuid: id,
|
|
||||||
is_fedration,
|
|
||||||
enabled: true,
|
|
||||||
network_pass: gen_uuid(),
|
|
||||||
header_pass: gen_uuid(),
|
|
||||||
auto_ip_net: IpSubnet::new(ipnet, ipnet_bitlen),
|
|
||||||
edges: DashSet::new(),
|
|
||||||
ip_to_edge_id: DashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
use tokio::net::UdpSocket;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {}
|
|
||||||
@ -1,4 +1,3 @@
|
|||||||
use sqlx::Error;
|
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, SDLanError>;
|
pub type Result<T> = std::result::Result<T, SDLanError>;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user