moved the sdlan-sn and sdlan to the outer workspace

This commit is contained in:
asxalex 2024-02-19 15:10:05 +08:00
parent e2aa6c9eb4
commit c12d62e4b1
12 changed files with 4 additions and 420 deletions

View File

@ -7,11 +7,10 @@ edition = "2021"
[dependencies]
aes = "0.8.4"
anyhow = "1.0.79"
byteorder = "1.5.0"
cbc = "0.1.2"
dashmap = "5.5.3"
lazy_static = "1.4.0"
# lazy_static = "1.4.0"
once_cell = "1.19.0"
rand = "0.8.5"
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_json = "1.0.113"
serde_repr = "0.1.18"
sqlx = { version = "0.7.3", features = [
"sqlx-mysql",
"mysql",
"runtime-tokio",
] }
structopt = "0.3.26"
sqlx = "0.7.3"
#structopt = "0.3.26"
tokio = { version = "1.36.0", features = ["full"] }
tracing = "0.1.40"
#tracing = "0.1.40"
tracing-appender = "0.2.3"
uuid = { version = "1.7.0", features = ["v4"] }

View File

@ -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)
)
}
}

View File

@ -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;

View File

@ -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(())
}

View File

@ -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
);

View File

@ -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)
}

View File

@ -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(())
}

View File

@ -1,8 +0,0 @@
mod sn;
pub use sn::*;
mod license;
pub use license::*;
mod params;
pub use params::*;

View File

@ -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,
}

View File

@ -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(),
}
}
}

View File

@ -1,4 +0,0 @@
use tokio::net::UdpSocket;
#[tokio::main]
async fn main() {}

View File

@ -1,4 +1,3 @@
use sqlx::Error;
use std::convert::From;
pub type Result<T> = std::result::Result<T, SDLanError>;